From cc09a733bffd7755737cf48d23f04dc13a06b5c1 Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Thu, 8 Jun 2023 22:03:37 -0300 Subject: [PATCH] Split the window_playerbreakdown_spells.lua into three more files --- Details.toc | 17 +- Details_Classic.toc | 17 +- Details_Wrath.toc | 17 +- .../breakdown_spells_genericframes.lua | 16 + .../breakdown_spells_spellframes.lua | 1525 +++++++++++++++++ .../breakdown_spells_targetframes.lua | 15 + .../window_playerbreakdown.lua | 8 +- .../window_playerbreakdown_auras.lua | 0 .../window_playerbreakdown_avoidance.lua | 0 .../window_playerbreakdown_charts | 0 .../window_playerbreakdown_compare.lua | 0 .../window_playerbreakdown_list.lua | 0 .../window_playerbreakdown_spells.lua | 1480 +--------------- .../window_playerbreakdown_spells_options.lua | 0 frames/window_main.lua | 7 +- 15 files changed, 1608 insertions(+), 1494 deletions(-) create mode 100644 frames/window_breakdown/breakdown_spells_genericframes.lua create mode 100644 frames/window_breakdown/breakdown_spells_spellframes.lua create mode 100644 frames/window_breakdown/breakdown_spells_targetframes.lua rename frames/{ => window_breakdown}/window_playerbreakdown.lua (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_auras.lua (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_avoidance.lua (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_charts (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_compare.lua (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_list.lua (100%) rename frames/{ => window_breakdown}/window_playerbreakdown_spells.lua (57%) rename frames/{ => window_breakdown}/window_playerbreakdown_spells_options.lua (100%) diff --git a/Details.toc b/Details.toc index 6a97ea65..66bc3abe 100644 --- a/Details.toc +++ b/Details.toc @@ -83,13 +83,16 @@ frames\window_options2.lua frames\window_options2_sections.lua frames\window_api.lua frames\window_cdtracker.lua -frames\window_playerbreakdown.lua -frames\window_playerbreakdown_list.lua -frames\window_playerbreakdown_compare.lua -frames\window_playerbreakdown_avoidance.lua -frames\window_playerbreakdown_auras.lua -frames\window_playerbreakdown_spells.lua -frames\window_playerbreakdown_spells_options.lua +frames\window_breakdown\window_playerbreakdown.lua +frames\window_breakdown\window_playerbreakdown_list.lua +frames\window_breakdown\window_playerbreakdown_compare.lua +frames\window_breakdown\window_playerbreakdown_avoidance.lua +frames\window_breakdown\window_playerbreakdown_auras.lua +frames\window_breakdown\window_playerbreakdown_spells.lua +frames\window_breakdown\window_playerbreakdown_spells_options.lua +frames\window_breakdown\breakdown_spells_genericframes.lua +frames\window_breakdown\breakdown_spells_spellframes.lua +frames\window_breakdown\breakdown_spells_targetframes.lua frames\window_report.lua frames\window_main.lua frames\window_custom.lua diff --git a/Details_Classic.toc b/Details_Classic.toc index 2db4db07..318e4cee 100644 --- a/Details_Classic.toc +++ b/Details_Classic.toc @@ -77,13 +77,16 @@ frames\window_options2.lua frames\window_options2_sections.lua frames\window_api.lua frames\window_cdtracker.lua -frames\window_playerbreakdown.lua -frames\window_playerbreakdown_list.lua -frames\window_playerbreakdown_compare.lua -frames\window_playerbreakdown_avoidance.lua -frames\window_playerbreakdown_auras.lua -frames\window_playerbreakdown_spells.lua -frames\window_playerbreakdown_spells_options.lua +frames\window_breakdown\window_playerbreakdown.lua +frames\window_breakdown\window_playerbreakdown_list.lua +frames\window_breakdown\window_playerbreakdown_compare.lua +frames\window_breakdown\window_playerbreakdown_avoidance.lua +frames\window_breakdown\window_playerbreakdown_auras.lua +frames\window_breakdown\window_playerbreakdown_spells.lua +frames\window_breakdown\window_playerbreakdown_spells_options.lua +frames\window_breakdown\breakdown_spells_genericframes.lua +frames\window_breakdown\breakdown_spells_spellframes.lua +frames\window_breakdown\breakdown_spells_targetframes.lua frames\window_report.lua frames\window_main.lua frames\window_custom.lua diff --git a/Details_Wrath.toc b/Details_Wrath.toc index 1ed6a6c4..15fb61db 100644 --- a/Details_Wrath.toc +++ b/Details_Wrath.toc @@ -77,13 +77,16 @@ frames\window_options2.lua frames\window_options2_sections.lua frames\window_api.lua frames\window_cdtracker.lua -frames\window_playerbreakdown.lua -frames\window_playerbreakdown_list.lua -frames\window_playerbreakdown_compare.lua -frames\window_playerbreakdown_avoidance.lua -frames\window_playerbreakdown_auras.lua -frames\window_playerbreakdown_spells.lua -frames\window_playerbreakdown_spells_options.lua +frames\window_breakdown\window_playerbreakdown.lua +frames\window_breakdown\window_playerbreakdown_list.lua +frames\window_breakdown\window_playerbreakdown_compare.lua +frames\window_breakdown\window_playerbreakdown_avoidance.lua +frames\window_breakdown\window_playerbreakdown_auras.lua +frames\window_breakdown\window_playerbreakdown_spells.lua +frames\window_breakdown\window_playerbreakdown_spells_options.lua +frames\window_breakdown\breakdown_spells_genericframes.lua +frames\window_breakdown\breakdown_spells_spellframes.lua +frames\window_breakdown\breakdown_spells_targetframes.lua frames\window_report.lua frames\window_main.lua frames\window_custom.lua diff --git a/frames/window_breakdown/breakdown_spells_genericframes.lua b/frames/window_breakdown/breakdown_spells_genericframes.lua new file mode 100644 index 00000000..59384c11 --- /dev/null +++ b/frames/window_breakdown/breakdown_spells_genericframes.lua @@ -0,0 +1,16 @@ + +local addonName, Details222 = ... +local breakdownWindow = Details.BreakdownWindow +local Loc = LibStub("AceLocale-3.0"):GetLocale("Details") +local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") +local unpack = unpack +local GetTime = GetTime +local CreateFrame = CreateFrame +local GetSpellLink = GetSpellLink +local GetSpellInfo = GetSpellInfo +local _GetSpellInfo = Details.GetSpellInfo +local GameTooltip = GameTooltip +local IsShiftKeyDown = IsShiftKeyDown +local DF = DetailsFramework +local tinsert = tinsert + diff --git a/frames/window_breakdown/breakdown_spells_spellframes.lua b/frames/window_breakdown/breakdown_spells_spellframes.lua new file mode 100644 index 00000000..656944c9 --- /dev/null +++ b/frames/window_breakdown/breakdown_spells_spellframes.lua @@ -0,0 +1,1525 @@ + +local addonName, Details222 = ... +local breakdownWindow = Details.BreakdownWindow +local Loc = LibStub("AceLocale-3.0"):GetLocale("Details") +local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") +local unpack = unpack +local GetTime = GetTime +local CreateFrame = CreateFrame +local GetSpellLink = GetSpellLink +local GetSpellInfo = GetSpellInfo +local _GetSpellInfo = Details.GetSpellInfo +local GameTooltip = GameTooltip +local IsShiftKeyDown = IsShiftKeyDown +local DF = DetailsFramework +local tinsert = tinsert + +local spellsTab = DetailsSpellBreakdownTab + +local CONST_BAR_HEIGHT = 20 +local CONST_SPELLSCROLL_LINEHEIGHT = 20 +local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]] +local CONST_SPELLBLOCK_DEFAULT_COLOR = {.4, .4, .4, 1} +local CONST_SPELLBLOCK_HEADERTEXT_COLOR = {.9, .8, 0, 1} +local CONST_SPELLBLOCK_HEADERTEXT_SIZE = 11 + +local spellBlockContainerSettings = { + amount = 6, --amount of block the container have + lineAmount = 3, --amount of line each block have +} + +local headerContainerType = spellsTab.headerContainerType + +local formatPetName = function(petName, spellName, ownerName) + --petName is raw (with the owner name) + local petNameWithoutOwner = petName:gsub((" <.*"), "") + + local texture = [[Interface\AddOns\Details\images\classes_small]] + + local bUseAlphaIcons = true + local specIcon = nil + local iconSize = 14 + + if (petName:len() == 0) then + return Details:AddClassOrSpecIcon(spellName, "PET", specIcon, iconSize, bUseAlphaIcons) + end + + petNameWithoutOwner = Details:AddClassOrSpecIcon(petNameWithoutOwner, "PET", specIcon, iconSize, bUseAlphaIcons) + + return spellName .. " |cFFCCBBBB" .. petNameWithoutOwner .. "|r" +end + +---some values required by the header sort key is not available in the spellTable, so they need to be calculated +---@param combatObject combat +---@param spellData spelltable|spelltableadv +---@param key string +---@return any +local getValueForHeaderSortKey = function(combatObject, spellData, key) + if (key == "critpercent") then + return Details.SpellTableMixin.GetCritPercent(spellData) + + elseif (key == "casts") then + local spellName = GetSpellInfo(spellData.id) + local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName) + return amountOfCasts + + elseif (key == "castavg") then + local spellName = GetSpellInfo(spellData.id) + local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName) + return Details.SpellTableMixin.GetCastAverage(spellData, amountOfCasts) + + elseif (key == "uptime") then + return combatObject:GetSpellUptime(spellsTab.GetActor():Name(), spellData.id) + + elseif (key == "healabsorbed") then + return spellData.absorbed + end +end + +---run when the user clicks the columnHeader +---@param headerFrame df_headerframe +---@param columnHeader df_headercolumnframe +local onColumnHeaderClickCallback = function(headerFrame, columnHeader) + ---@type string + local containerType = headerContainerType[headerFrame] + + local scrollFrame = spellsTab.GetScrollFrameByContainerType(containerType) + scrollFrame:Refresh() + + local instance = spellsTab.GetInstance() + instance:RefreshWindow(true) +end + +---on enter function for the spell target frame +---@param targetFrame breakdowntargetframe +local onEnterSpellTarget = function(targetFrame) + --the spell target frame is created in the statusbar which is placed above the line frame + local lineBar = targetFrame:GetParent():GetParent() + local spellId = targetFrame.spellId + + ---@type actor + local actorObject = Details:GetActorObjectFromBreakdownWindow() + + local targets + if (targetFrame.bIsMainLine) then + ---@type spelltableadv + local bkSpellData = targetFrame.bkSpellData + targets = actorObject:BuildSpellTargetFromBreakdownSpellData(bkSpellData) + else + local spellTable = targetFrame.spellTable + targets = actorObject:BuildSpellTargetFromSpellTable(spellTable) + end + + ---@type number the top value of targets + local topValue = targets[1] and targets[1][2] or 0 + + local cooltip = GameCooltip + cooltip:Preset(2) + + for targetIndex, targetTable in ipairs(targets) do + local targetName = targetTable[1] + local value = targetTable[2] + cooltip:AddLine(targetIndex .. ". " .. targetName, Details:Format(value)) + GameCooltip:AddIcon(CONST_TARGET_TEXTURE, 1, 1, 14, 14) + Details:AddTooltipBackgroundStatusbar(false, value / topValue * 100) + end + + cooltip:SetOwner(targetFrame) + cooltip:Show() +end + +local onLeaveSpellTarget = function(self) + GameTooltip:Hide() + GameCooltip:Hide() + self:GetParent():GetParent():GetScript("OnLeave")(self:GetParent():GetParent()) + self.texture:SetAlpha(.7) + self:SetAlpha(.7) +end + +--create a details bar on the right side of the window +local onEnterSpellBlock = function(spellBlock) --info background is the 6 bars in the right side of the window? + spellBlock.overlay:Show() + spellBlock.reportButton:Show() +end + +local onLeaveSpellBlock = function(spellBlock) + spellBlock.overlay:Hide() + spellBlock.reportButton:Hide() +end + +local onEnterInfoReport = function(self) + Details.FadeHandler.Fader(self:GetParent().overlay, 0) + Details.FadeHandler.Fader(self, 0) +end + +local onLeaveInfoReport = function(self) + Details.FadeHandler.Fader(self:GetParent().overlay, 1) + Details.FadeHandler.Fader(self, 1) +end + +---run this function when the mouse hover over a breakdownspellbar +---@param spellBar breakdownspellbar +---@param motion boolean|nil +local onEnterSpellBar = function(spellBar, motion) --parei aqui: precisa por nomes nas funções e formatar as linhas das funcções + --all values from spellBar are cached values + --check if there's a spellbar selected, if there's one, ignore the mouseover + if (spellsTab.HasSelectedSpellBar() and motion) then + return + end + + spellsTab.currentSpellBar = spellBar + + ---@type instance + local instance = spellsTab.GetInstance() + + ---@type combat + local combatObject = spellsTab.GetCombat() + + ---@type number, number + local mainAttribute, subAttribute = instance:GetDisplay() + + ---@type breakdownspellblockframe + local spellBlockContainer = spellsTab.GetSpellBlockFrame() + spellBlockContainer:ClearBlocks() + + ---@type number + local spellId = spellBar.spellId + + ---@type number + local elapsedTime = spellBar.combatTime --this should be actorObject:Tempo() + + ---@type string + local actorName = spellsTab.GetActor():Name() + + ---@type spelltable + local spellTable = spellBar.spellTable + + if (IsShiftKeyDown()) then + if (type(spellId) == "number") then + GameCooltip:Preset(2) + GameCooltip:SetOwner(spellBar) + + --if this is an actor header (e.g. a pet bar showing its nested spells) + if (spellBar.bkSpellData.bIsActorHeader) then + local petActor = combatObject:GetContainer(mainAttribute):GetActor(spellBar.bkSpellData.actorName) + local textToEditor = "" + for key, value in pairs(petActor) do + if (type(value) ~= "function" and type(value) ~= "table") then + textToEditor = textToEditor .. key .. " = " .. tostring(value) .. "\n" + end + + breakdownWindow.dumpDataFrame:Show() + breakdownWindow.dumpDataFrame.luaEditor:SetText(textToEditor) + --hide the scroll bar + _G["DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar"]:Hide() + end + + GameCooltip:AddLine("npc id: " .. petActor.aID) + GameCooltip:Show() + return + end + + ---@type actor + local thisActor = spellsTab.GetActor() + + ---@type spelltable + local thisSpellTable = thisActor:GetSpell(spellId) + + if (not thisSpellTable) then + local petName = spellBar.bkSpellData.actorName + local actorContainer = combatObject:GetContainer(mainAttribute) + local petObject = actorContainer:GetActor(petName) + if (petObject) then + thisSpellTable = petObject:GetSpell(spellId) + end + end + + GameCooltip:AddLine("spell id: " .. thisSpellTable.id) + GameCooltip:Show() --add the icon for the bar bar with nested spells (place the icon of the npc or pet) + + local textToEditor = "" + for key, value in pairs(thisSpellTable) do + if (type(value) ~= "function" and type(value) ~= "table") then + textToEditor = textToEditor .. key .. " = " .. tostring(value) .. "\n" + end + end + + breakdownWindow.dumpDataFrame:Show() + breakdownWindow.dumpDataFrame.luaEditor:SetText(textToEditor) + --hide the scroll bar + _G["DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar"]:Hide() + end + + elseif (breakdownWindow.dumpDataFrame:IsShown()) then + breakdownWindow.dumpDataFrame:Hide() + end + + if (spellId == 98021) then --spirit link totem + GameTooltip:SetOwner(spellBar, "ANCHOR_TOPLEFT") + GameTooltip:AddLine(Loc ["STRING_SPIRIT_LINK_TOTEM_DESC"]) + GameTooltip:Show() + end + + ---@type trinketdata + local trinketData = Details:GetTrinketData() + + ---@type number + local blockIndex = 1 + + --get the first spell block to use as summary + ---@type breakdownspellblock + local summaryBlock = spellBlockContainer:GetBlock(blockIndex) + summaryBlock:Show() + summaryBlock:SetValue(50) + summaryBlock:SetValue(100) + + if (mainAttribute == DETAILS_ATTRIBUTE_DAMAGE) then + --bounce to damage class to handle the spell details + if (subAttribute == 1 or subAttribute == 2 or subAttribute == 6) then + Details.atributo_damage:BuildSpellDetails(spellBar, spellBlockContainer, blockIndex, summaryBlock, spellId, elapsedTime, actorName, spellTable, trinketData, combatObject) + end + + --need to know how many blocks the damage class used + local blocksInUse = spellBlockContainer:GetBlocksInUse() + local maxBlocks = spellBlockContainer:GetBlocksAmount() + + for i = blocksInUse + 1, math.min(maxBlocks, 4) do --in the current state of the breakdown, showing 5 will overlap with the phase container + spellBlockContainer:ShowEmptyBlock(i) + end + + elseif (mainAttribute == DETAILS_ATTRIBUTE_HEAL) then --this should run within the heal class ~healing + ---@type number + local totalHits = spellTable.counter + + --healing section showing healing done sub section + blockIndex = blockIndex + 1 + + do --update the texts in the summary block + local blockLine1, blockLine2, blockLine3 = summaryBlock:GetLines() + + local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or "(?)" + blockLine1.leftText:SetText(Loc ["STRING_CAST"] .. ": " .. totalCasts) --total amount of casts + blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime + + blockLine2.leftText:SetText(Loc ["STRING_HEAL"]..": " .. Details:Format(spellTable.total)) --total damage + blockLine2.rightText:SetText(Details:GetSpellSchoolFormatedName(spellTable.spellschool)) --spell school + + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:Format(spellBar.average)) --average damage + blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps + end + + --check if there's normal hits and build the block + ---@type number + local normalHitsAmt = spellTable.n_amt + + if (normalHitsAmt > 0) then + ---@type breakdownspellblock + local normalHitsBlock = spellBlockContainer:GetBlock(blockIndex) + normalHitsBlock:Show() + blockIndex = blockIndex + 1 + + local percent = normalHitsAmt / math.max(totalHits, 0.0001) * 100 + normalHitsBlock:SetValue(percent) + normalHitsBlock.sparkTexture:SetPoint("left", normalHitsBlock, "left", percent / 100 * normalHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + + local blockLine1, blockLine2, blockLine3 = normalHitsBlock:GetLines() + blockLine1.leftText:SetText(Loc ["STRING_NORMAL_HITS"]) + blockLine1.rightText:SetText(normalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", normalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") + + blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_min)) + blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_max)) + + local normalAverage = spellTable.n_total / math.max(normalHitsAmt, 0.0001) + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(normalAverage)) + + local tempo = (elapsedTime * spellTable.n_total) / math.max(spellTable.total, 0.001) + local normalAveragePercent = spellBar.average / normalAverage * 100 + local normalTempoPercent = normalAveragePercent * tempo / 100 + blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellTable.n_total / normalTempoPercent)) + end + + ---@type number + local criticalHitsAmt = spellTable.c_amt + if (criticalHitsAmt > 0) then + ---@type breakdownspellblock + local critHitsBlock = spellBlockContainer:GetBlock(blockIndex) + critHitsBlock:Show() + blockIndex = blockIndex + 1 + + local percent = criticalHitsAmt / math.max(totalHits, 0.0001) * 100 + critHitsBlock:SetValue(percent) + critHitsBlock.sparkTexture:SetPoint("left", critHitsBlock, "left", percent / 100 * critHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + + local blockLine1, blockLine2, blockLine3 = critHitsBlock:GetLines() + blockLine1.leftText:SetText(Loc ["STRING_CRITICAL_HITS"]) + blockLine1.rightText:SetText(criticalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", criticalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") + + blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_min)) + blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_max)) + + local critAverage = spellTable.c_total / math.max(criticalHitsAmt, 0.0001) + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage)) + + local tempo = (elapsedTime * spellTable.c_total) / math.max(spellTable.total, 0.001) + local critAveragePercent = spellBar.average / critAverage * 100 + local critTempoPercent = critAveragePercent * tempo / 100 + blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellTable.c_total / critTempoPercent)) + end + + ---@type number + local overheal = spellTable.overheal or 0 + if (overheal > 0) then + --blockIndex = blockIndex + 1 --skip one block + ---@type breakdownspellblock + local overhealBlock = spellBlockContainer:GetBlock(blockIndex) + overhealBlock:Show() + blockIndex = blockIndex + 1 + + local blockName + if (spellTable.is_shield) then + blockName = Loc ["STRING_SHIELD_OVERHEAL"] + else + blockName = Loc ["STRING_OVERHEAL"] + end + + local percent = overheal / (overheal + spellTable.total) * 100 + overhealBlock:SetValue(percent) + overhealBlock.sparkTexture:SetPoint("left", overhealBlock, "left", percent / 100 * overhealBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + + overhealBlock:SetColor(1, 0, 0, 0.4) + + local blockLine1, blockLine2, blockLine3 = overhealBlock:GetLines() + blockLine1.leftText:SetText(blockName) + + local overhealString = Details:CommaValue(overheal) + local overhealText = overhealString .. " / " .. string.format("%.1f", percent) .. "%" + blockLine1.rightText:SetText(overhealText) + end + end + + --effects on entering the bar line + spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT + 1) + spellBar:SetAlpha(1) + spellBar.spellIcon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT + 2, CONST_SPELLSCROLL_LINEHEIGHT + 2) + spellBar.spellIcon:SetAlpha(1) +end + +---run this function when the mouse leaves a breakdownspellbar +---@param spellBar breakdownspellbar +local onLeaveSpellBar = function(spellBar) + spellsTab.currentSpellBar = nil + + --remove effects on entering the bar line + spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT) + spellBar:SetAlpha(0.9) + + GameTooltip:Hide() + GameCooltip:Hide() + + --clear spell blocks + if (not spellsTab.HasSelectedSpellBar()) then + spellsTab.GetSpellBlockFrame():ClearBlocks() + end + + if (breakdownWindow.dumpDataFrame:IsShown()) then + breakdownWindow.dumpDataFrame:Hide() + end +end + +---on mouse down a breakdownspellbar in the breakdown window +---@param spellBar breakdownspellbar +---@param button string +local onMouseDownBreakdownSpellBar = function(spellBar, button) + local x, y = _G.GetCursorPosition() + spellBar.cursorPosX = math.floor(x) + spellBar.cursorPosY = math.floor(y) +end + +---on mouse up a breakdownspellbar in the breakdown window +---@param spellBar breakdownspellbar +---@param button string +local onMouseUpBreakdownSpellBar = function(spellBar, button) + spellBar.onMouseUpTime = GetTime() + + ---@type number, number + local x, y = _G.GetCursorPosition() + x = math.floor(x) + y = math.floor(y) + + ---@type boolean + local bIsMouseInTheSamePosition = (x == spellBar.cursorPosX) and (y == spellBar.cursorPosY) + + --if the mouse is in the same position, then the user clicked the bar + if (bIsMouseInTheSamePosition) then + spellsTab.SelectSpellBar(spellBar) + end +end + +local onEnterSpellIconFrame = function(self) + local line = self:GetParent() + if (line.spellId and type(line.spellId) == "number") then + local spellName = _GetSpellInfo(line.spellId) + if (spellName) then + GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT") + Details:GameTooltipSetSpellByID(line.spellId) + GameTooltip:Show() + end + end + line:GetScript("OnEnter")(line) +end + +local onLeaveSpellIconFrame = function(self) + GameTooltip:Hide() + self:GetParent():GetScript("OnLeave")(self:GetParent()) +end + +-------------------------------------------------------------------------------------------------------------------------------------------- +--Spell Blocks + +local spellBlockMixin = { + ---get one of the three lines containing fontstrings to show data + ---line 1 is the top line, line 2 is the middle line and line 3 is the bottom line + ---@param self breakdownspellblock + ---@param lineIndex number + ---@return breakdownspellblockline + GetLine = function(self, lineIndex) + ---@type breakdownspellblockline + local line = self.Lines[lineIndex] + return line + end, + + ---return all lines in the spell block, all spell block have 3 lines + ---@param self breakdownspellblock + ---@return breakdownspellblockline, breakdownspellblockline, breakdownspellblockline + GetLines = function(self) + return unpack(self.Lines) + end, + + ---@param self breakdownspellblock + SetColor = function(self, ...) + local r, g, b, a = DF:ParseColors(...) + self.statusBarTexture:SetColorTexture(r, g, b, a) + end, +} + +---create a spell block into the spellblockcontainer +---@param spellBlockContainer breakdownspellblockframe +---@param index number +---@return breakdownspellblock +function spellsTab.CreateSpellBlock(spellBlockContainer, index) --~breakdownspellblock ~create ~spellblocks + ---@type breakdownspellblock + local spellBlock = CreateFrame("statusbar", "$parentBlock" .. index, spellBlockContainer, "BackdropTemplate") + DetailsFramework:Mixin(spellBlock, spellBlockMixin) + + local statusBarTexture = spellBlock:CreateTexture("$parentTexture", "artwork") + statusBarTexture:SetColorTexture(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR)) + statusBarTexture:SetPoint("topleft", spellBlock, "topleft", 1, -1) + statusBarTexture:SetPoint("bottomleft", spellBlock, "bottomleft", 1, 1) + spellBlock.statusBarTexture = statusBarTexture + + spellBlock:SetScript("OnEnter", onEnterSpellBlock) + spellBlock:SetScript("OnLeave", onLeaveSpellBlock) + spellBlock:SetScript("OnValueChanged", function() + statusBarTexture:SetWidth(spellBlock:GetValue() / 100 * spellBlock:GetWidth()) + end) + + spellBlock:SetMinMaxValues(0, 100) + spellBlock:SetValue(100) + + --set the backdrop to have a 8x8 edge file + spellsTab.ApplyStandardBackdrop(spellBlock) + + --create the lines which will host the texts + spellBlock.Lines = {} + for i = 1, spellBlockContainerSettings.lineAmount do + ---@type breakdownspellblockline + local line = CreateFrame("frame", "$parentLine" .. i, spellBlock) + spellBlock.Lines[i] = line + + line.leftText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") + line.centerText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") + line.rightText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") + + line.leftText:SetPoint("left", line, "left", 2, 0) + line.leftText:SetJustifyH("left") + line.centerText:SetPoint("center", line, "center", 0, 0) + line.centerText:SetJustifyH("center") + line.rightText:SetPoint("right", line, "right", -2, 0) + line.rightText:SetJustifyH("right") + end + + --overlay texture which fade in and out when the spell block is hovered over + --is only possible to hover over a spell block when the spellbar is selected + spellBlock.overlay = spellBlock:CreateTexture("$parentOverlay", "artwork") + spellBlock.overlay:SetTexture("Interface\\AddOns\\Details\\images\\overlay_detalhes") + spellBlock.overlay:SetPoint("topleft", spellBlock, "topleft", -8, 8) + spellBlock.overlay:SetPoint("bottomright", spellBlock, "bottomright", 26, -14) + Details.FadeHandler.Fader(spellBlock.overlay, 1) --hide + + --report button, also only shown when the spell block is hovered over + spellBlock.reportButton = Details.gump:NewDetailsButton(spellBlock, nil, nil, Details.Reportar, Details.playerDetailWindow, 10 + index, 16, 16, + "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", nil, "DetailsJanelaInfoReport1") + Details.FadeHandler.Fader(spellBlock.reportButton, 1) --hide + spellBlock.reportButton:SetScript("OnEnter", onEnterInfoReport) + spellBlock.reportButton:SetScript("OnLeave", onLeaveInfoReport) + + --spark texture + spellBlock.sparkTexture = spellBlock:CreateTexture("$parentOverlaySparkTexture", "overlay") + spellBlock.sparkTexture:SetTexture("Interface\\AddOns\\Details\\images\\bar_detalhes2_end") + spellBlock.sparkTexture:SetBlendMode("ADD") + + local gradientDown = DetailsFramework:CreateTexture(spellBlock, {gradient = "vertical", fromColor = {0, 0, 0, 0.1}, toColor = "transparent"}, 1, spellBlock:GetHeight(), "background", {0, 1, 0, 1}) + gradientDown:SetPoint("bottoms") + spellBlock.gradientTexture = gradientDown + spellBlock.gradientTexture:Hide() + + return spellBlock +end + +local spellBlockContainerMixin = { + ---refresh all the spellblocks in the container ~UpdateBlocks + ---this function adjust the frame properties, does not update the data shown on them + ---@param self breakdownspellblockframe + UpdateBlocks = function(self) --~update + ---@type number, number + local width, height = Details.breakdown_spell_tab.blockcontainer_width, Details.breakdown_spell_tab.blockcontainer_height + local blockHeight = Details.breakdown_spell_tab.blockspell_height + local backgroundColor = Details.breakdown_spell_tab.blockspell_backgroundcolor + local borderColor = Details.breakdown_spell_tab.blockspell_bordercolor + local padding = Details.breakdown_spell_tab.blockspell_padding * -1 + local color = Details.breakdown_spell_tab.blockspell_color + + self:SetSize(width, height) + + backgroundColor[1], backgroundColor[2], backgroundColor[3], backgroundColor[4] = 0.05, 0.05, 0.05, 0.2 + color[1], color[2], color[3], color[4] = 0.6, 0.6, 0.6, 0.55 + + for i = 1, #self.SpellBlocks do + ---@type breakdownspellblock + local spellBlock = self.SpellBlocks[i] + + spellBlock:SetSize(width - 2, blockHeight) + spellBlock:SetPoint("topleft", self, "topleft", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding)) + spellBlock:SetPoint("topright", self, "topright", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding)) + + spellBlock.sparkTexture:SetSize(Details.breakdown_spell_tab.blockspell_spark_width, blockHeight) + spellBlock.sparkTexture:SetShown(Details.breakdown_spell_tab.blockspell_spark_show) + spellBlock.sparkTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_spark_color)) + spellBlock.reportButton:SetPoint("bottomright", spellBlock.overlay, "bottomright", -2, 2) + spellBlock.gradientTexture:SetHeight(blockHeight) + + spellBlock:SetBackdropBorderColor(unpack(borderColor)) --border color + spellBlock.statusBarTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_color)) --bar color + + local lineHeight = blockHeight * 0.2687 + + --update the lines + local previousLine + for o = 1, spellBlockContainerSettings.lineAmount do + ---@type breakdownspellblockline + local line = spellBlock.Lines[o] + line:SetSize(width - 2, lineHeight) + if (previousLine) then + line:SetPoint("topleft", previousLine, "bottomleft", 0, -2) + else + line:SetPoint("topleft", spellBlock, "topleft", 1, -2) + end + previousLine = line + end + end + end, + + ---@param self breakdownspellblockframe + ClearBlocks = function(self) + for i = 1, self:GetBlocksAmount() do + ---@type breakdownspellblock + local spellBlock = self.SpellBlocks[i] + spellBlock:Hide() + + spellBlock:SetColor(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR)) + + --set the status bar value to zero + spellBlock:SetValue(0) + spellBlock.statusBarTexture:Show() + spellBlock.sparkTexture:Show() + + --clear the text shown in their lines + for o = 1, 3 do + spellBlock.Lines[o].leftText:SetText("") + + --set the color of the top left text in the block, the text is used as header text + if (o == 1) then + DF:SetFontColor(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_COLOR) + DF:SetFontSize(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_SIZE) + end + + spellBlock.Lines[o].centerText:SetText("") + spellBlock.Lines[o].rightText:SetText("") + end + end + + for i = 1, math.min(self:GetBlocksAmount(), 4) do + self:ShowEmptyBlock(i) + end + + self.blocksInUse = 0 + end, + + ---show the empty block in the container, this is done to preview where the rectangle will be + ---@param self breakdownspellblockframe + ---@param index number + ShowEmptyBlock = function(self, index) + local spellBlock = self.SpellBlocks[index] + spellBlock:Show() + spellBlock:SetValue(0) + spellBlock.statusBarTexture:Hide() + spellBlock.sparkTexture:Hide() + end, + + ---get a breakdownspellblock from the container + ---@param self breakdownspellblockframe + ---@param index number + ---@return breakdownspellblock + GetBlock = function(self, index) + self.blocksInUse = self.blocksInUse + 1 + local spellBlock = self.SpellBlocks[index] + spellBlock.statusBarTexture:Show() + spellBlock.sparkTexture:Show() + return self.SpellBlocks[index] + end, + + ---get the amount of blocks in use + ---@param self breakdownspellblockframe + ---@return number + GetBlocksInUse = function(self) + return self.blocksInUse + end, + + ---get the total blocks created + ---@param self breakdownspellblockframe + ---@return number + GetBlocksAmount = function(self) + return #self.SpellBlocks + end, +} + +---create the spell blocks which shows the critical hits, normal hits, etc +---@param tabFrame tabframe +---@return breakdownspellblockframe +function spellsTab.CreateSpellBlockContainer(tabFrame) --~create ~createblock ~spellblock ~block ~container + --create a container for the scrollframe + local options = { + width = Details.breakdown_spell_tab.blockcontainer_width, + height = Details.breakdown_spell_tab.blockcontainer_height, + is_locked = Details.breakdown_spell_tab.blockcontainer_islocked, + can_move = false, + can_move_children = false, + use_bottom_resizer = true, + use_right_resizer = true, + } + + ---@type df_framecontainer + local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer") + container:SetPoint("topleft", spellsTab.GetSpellScrollContainer(), "topright", 26, 0) + container:SetFrameLevel(tabFrame:GetFrameLevel() + 10) + spellsTab.BlocksContainerFrame = container + + local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue) + if (frameContainer:IsShown()) then + if (settingName == "UpdateSize") then + --get the tabFrame width and height + local width, height = tabFrame:GetSize() + local containerWidth + + --get with of the container holding the spellscrollframe + if (spellsTab.GetSpellScrollContainer():IsShown()) then + containerWidth = spellsTab.GetSpellScrollContainer():GetWidth() + + elseif (spellsTab.GetGenericScrollContainer():IsShown()) then + containerWidth = spellsTab.GetGenericScrollContainer():GetWidth() + end + + --calculate the widh of the spellblockcontainer by subtracting the width of the spellscrollframe container from the tabFrame width + local spellBlockContainerWidth = width - containerWidth - 38 + --set the width of the spellblockcontainer + container:SetWidth(spellBlockContainerWidth) + + elseif (settingName == "height") then + ---@type number + local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight() + Details.breakdown_spell_tab.blockcontainer_height = settingValue + spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1) + + elseif (settingName == "width") then + Details.breakdown_spell_tab.blockcontainer_width = settingValue + + elseif (settingName == "is_locked") then + Details.breakdown_spell_tab.blockcontainer_islocked = settingValue + end + + --update the spell blocks + spellsTab.GetSpellBlockFrame():UpdateBlocks() + + if (spellsTab.GetSelectedSpellBar()) then + onEnterSpellBar(spellsTab.GetSelectedSpellBar()) + end + end + end + container:SetSettingChangedCallback(settingChangedCallbackFunction) + + --create the container which will hold the spell blocks + ---@type breakdownspellblockframe + local spellBlockFrame = CreateFrame("Frame", "$parentSpellBlockContainer", container, "BackdropTemplate") + spellBlockFrame:EnableMouse(false) + spellBlockFrame:SetResizable(false) + spellBlockFrame:SetMovable(false) + spellBlockFrame:SetAllPoints() + DetailsFramework:Mixin(spellBlockFrame, spellBlockContainerMixin) + + tabFrame.SpellBlockFrame = spellBlockFrame + spellsTab.SpellBlockFrame = spellBlockFrame + + container:RegisterChildForDrag(spellBlockFrame) + + spellBlockFrame.SpellBlocks = {} + spellBlockFrame.blocksInUse = 0 + + --create the spell blocks within the spellBlockFrame + for i = 1, spellBlockContainerSettings.amount do + ---@type breakdownspellblock + local spellBlock = spellsTab.CreateSpellBlock(spellBlockFrame, i) + table.insert(spellBlockFrame.SpellBlocks, spellBlock) + --size and point are set on ~UpdateBlocks + end + + spellBlockFrame:UpdateBlocks() + + return spellBlockFrame +end + +function spellsTab.UpdateShownSpellBlock() + if (spellsTab.currentSpellBar) then + onEnterSpellBar(spellsTab.currentSpellBar) + + elseif (spellsTab.GetSelectedSpellBar()) then + onEnterSpellBar(spellsTab.GetSelectedSpellBar()) + end +end + + +--logistics: class_damage build the list of spells, send it to window_playerbreakdown, which gets the current summary tab and send the data for it +--in this tab, the data is sent to the refresh function + +local onClickExpandButton = function(expandButton, button) + ---@type breakdownspellbar + local spellBar = expandButton:GetParent() + ---@type table + local scrolFrame = spellBar:GetParent() + ---@type boolean + local bIsSpellExpaded = expandButton.bIsSpellExpaded + + --check if the one of the expanded bars was a selected spellbar and deselect + --get the current selected spellbar + ---@type breakdownspellbar + local selectedSpellBar = spellsTab.GetSelectedSpellBar() + + if (bIsSpellExpaded) then --it's already expended, it'll close the expanded spellbars + --check if the selected spellbar is one of the expanded spellbars and deselect it + for i = 1, #spellBar.ExpandedChildren do + ---@type breakdownspellbar + local expandedSpellBar = spellBar.ExpandedChildren[i] + if (expandedSpellBar == selectedSpellBar) then + --deselect the spellbar + spellsTab.UnSelectSpellBar() + break + end + end + else + spellsTab.UnSelectSpellBar() + end + + --todo: check is any other bar has expanded state true, and close the expand (or not) + + --toggle this spell expand mode + Details222.BreakdownWindow.SetSpellAsExpanded(expandButton.petName or expandButton.spellId, not bIsSpellExpaded) + + --call the refresh function of the window + ---@type instance + local instanceObject = spellsTab.GetInstance() + instanceObject:RefreshWindow(true) +end + + +---update a line using the data passed +---@param spellBar breakdownspellbar +---@param index number spell position (from best to wrost) +---@param actorName string +---@param combatObject combat +---@param scrollFrame table +---@param headerTable table +---@param bkSpellData spelltableadv +---@param spellTableIndex number +---@param totalValue number +---@param topValue number +---@param bIsMainLine boolean if true this is the line which has all the values of the spell merged +---@param sortKey string +---@param spellTablesAmount number +local updateSpellBar = function(spellBar, index, actorName, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, sortKey, spellTablesAmount) + --scrollFrame is defined as a table which is false, scrollFrame is a frame + + local textIndex = 1 + for headerIndex = 1, #headerTable do + ---@type number + local spellId + ---@type number + local value + ---@type spelltable + local spellTable + + spellBar.bkSpellData = bkSpellData + + local petName = "" + ---@type boolean @if true, this is the main line of an actor which has its spells nested in the bkSpellData.nestedData + local bIsActorHeader = bkSpellData.bIsActorHeader + + if (bIsMainLine and bIsActorHeader) then + spellTable = bkSpellData + value = bkSpellData.total + spellId = 0 + petName = actorName + + elseif (bIsMainLine) then + spellTable = bkSpellData + value = bkSpellData.total + spellId = bkSpellData.id + petName = bkSpellData.nestedData[spellTableIndex].actorName + + else + spellTable = bkSpellData.nestedData[spellTableIndex].spellTable + value = spellTable.total + spellId = spellTable.id + + --if isn't a spell from a nested actor, then it can use the pet name in the spell name + if (not bkSpellData.nestedData[spellTableIndex].bIsActorHeader) then + petName = bkSpellData.nestedData[spellTableIndex].actorName + end + + spellBar.bIsExpandedSpell = true + end + + spellBar.spellId = spellId + + ---@cast spellTable spelltable + spellBar.spellTable = spellTable + + ---@type string, number, any + local spellName, _, spellIcon = Details.GetSpellInfo(spellId) + if (not spellName) then + spellName = actorName + ---@type npcid + local npcId = tonumber(bkSpellData.npcId) or 0 + spellIcon = Details.NpcIdToIcon[npcId] or bkSpellData.actorIcon or "" + end + + ---@type number + local amtCasts = combatObject:GetSpellCastAmount(actorName, spellName) + spellBar.amountCasts = amtCasts + + ---@type number + local uptime = combatObject:GetSpellUptime(actorName, spellId) + + ---@type number + local combatTime = combatObject:GetCombatTime() + + --statusbar size by percent + if (topValue > 0) then + local barValue = spellTable[sortKey] or getValueForHeaderSortKey(combatObject, spellTable, sortKey) + spellBar.statusBar:SetValue(barValue / topValue * 100) + else + spellBar.statusBar:SetValue(0) + end + + if (petName ~= "") then + --if is a pet spell and has more pets nested || nop, now is a pet with its spells nested + if (spellTablesAmount > 1 and bIsMainLine) then + spellName = formatPetName("", spellName, "") --causing error as spellName is nil + elseif (bIsMainLine) then + spellName = formatPetName(petName, spellName, actorName) + else + spellName = formatPetName(petName, "", "") + end + end + + spellBar.spellId = spellId + spellBar.spellIconFrame.spellId = spellId + + spellBar.statusBar.backgroundTexture:SetAlpha(Details.breakdown_spell_tab.spellbar_background_alpha) + + --statusbar color by school + local r, g, b = Details:GetSpellSchoolColor(spellTable.spellschool or 1) + spellBar.statusBar:SetStatusBarColor(r, g, b, 0.963) + + spellBar.average = value / spellTable.counter + spellBar.combatTime = combatTime + + ---@type fontstring + local text = spellBar.InLineTexts[textIndex] + local header = headerTable[headerIndex] + + if (header.name == "icon") then + spellBar.spellIcon:Show() + spellBar.spellIcon:SetTexture(spellIcon) + spellBar.spellIcon:SetAlpha(0.92) + spellBar:AddFrameToHeaderAlignment(spellBar.spellIconFrame) + + elseif (header.name == "target") then --the tab does not have knownledge about the targets of the spell, it must be passed over + ---@type breakdowntargetframe + local targetsSquareFrame = spellBar.targetsSquareFrame + targetsSquareFrame:Show() + targetsSquareFrame.spellId = spellId + targetsSquareFrame.bkSpellData = spellTable + targetsSquareFrame.spellTable = spellTable + targetsSquareFrame.bIsMainLine = bIsMainLine + spellBar:AddFrameToHeaderAlignment(targetsSquareFrame) + + elseif (header.name == "rank") then + text:SetText(index) + spellBar:AddFrameToHeaderAlignment(text) + spellBar.rank = index + textIndex = textIndex + 1 + + elseif (header.name == "expand") then + text:SetText("") + spellBar:AddFrameToHeaderAlignment(spellBar.expandButton) + textIndex = textIndex + 1 + + if (bkSpellData.bCanExpand and bIsMainLine) then + spellBar.expandButton:Show() + local bIsSpellExpaded = Details222.BreakdownWindow.IsSpellExpanded(bIsActorHeader and actorName or spellId) + spellBar.expandButton.spellId = bIsActorHeader and actorName or spellId + spellBar.expandButton.bIsSpellExpaded = bIsSpellExpaded + spellBar.expandButton:SetScript("OnClick", onClickExpandButton) + + --update the texture taking the state of the expanded value + if (bIsSpellExpaded) then + spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]]) + spellBar.expandButton.texture:SetTexCoord(0, 1, 1, 0) + else + spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]]) + spellBar.expandButton.texture:SetTexCoord(0, 1, 0, 1) + end + + spellBar.expandButton.texture:SetAlpha(0.7) + spellBar.expandButton.texture:SetSize(16, 16) + end + + elseif (header.name == "name") then + text:SetText(Details:RemoveOwnerName(spellName)) + spellBar.name = spellName + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "amount") then + text:SetText(Details:Format(value)) + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "persecond") then + spellBar.perSecond = value / combatTime + + ---@type string + local perSecondFormatted = Details:Format(spellBar.perSecond) + text:SetText(perSecondFormatted) + + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "percent") then + spellBar.percent = value / totalValue * 100 + ---@type string + local percentFormatted = string.format("%.1f", spellBar.percent) .. "%" + text:SetText(percentFormatted) + + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "casts") then + text:SetText(amtCasts) + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "critpercent") then + text:SetText(string.format("%.1f", spellTable.c_amt / (spellTable.counter) * 100) .. "%") + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "hits") then + text:SetText(spellTable.counter) + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "castavg") then + if (amtCasts > 0) then + spellBar.castAverage = value / amtCasts + text:SetText(Details:Format(spellBar.castAverage)) + else + text:SetText("0") + end + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "uptime") then --need to get the uptime of the spell with the biggest uptime + text:SetText(string.format("%.1f", uptime / combatTime * 100) .. "%") + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "overheal" and spellTable.overheal) then + if (spellTable.overheal > 0) then + local totalHeal = spellTable.overheal + value + text:SetText(Details:ToK2(spellTable.overheal) .. " (" .. math.floor(spellTable.overheal / totalHeal * 100) .. "%)") + else + text:SetText("0%") + end + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + + elseif (header.name == "absorbed") then + text:SetText(Details:Format(spellTable.absorbed or 0)) + spellBar:AddFrameToHeaderAlignment(text) + textIndex = textIndex + 1 + end + end + + spellBar:AlignWithHeader(scrollFrame.Header, "left") +end + +---get a spell bar from the scroll box, if it doesn't exist, return nil +---@param scrollFrame table +---@param lineIndex number +---@return breakdownspellbar +local getSpellBar = function(scrollFrame, lineIndex) + ---@type breakdownspellbar + local spellBar = scrollFrame:GetLine(lineIndex) + + spellBar.bIsExpandedSpell = false + + Details:Destroy(spellBar.ExpandedChildren) + + --reset header alignment + spellBar:ResetFramesToHeaderAlignment() + + spellsTab.UpdateBarSettings(spellBar) + + --reset columns, hiding them + spellBar.spellIcon:Hide() + spellBar.expandButton:Hide() + spellBar.targetsSquareFrame:Hide() + for inLineIndex = 1, #spellBar.InLineTexts do + spellBar.InLineTexts[inLineIndex]:SetText("") + end + + return spellBar +end + +---refresh the data shown in the spells scroll box +---@param scrollFrame table +---@param scrollData breakdownspelldatalist +---@param offset number +---@param totalLines number +local refreshSpellsFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshspells ~refreshfunc ~refresh ~refreshs + ---@type number + local topValue = scrollFrame.topValue + ---@type number + local totalValue = scrollData.totalValue + ---@type actor + local actorObject = spellsTab.GetActor() + ---@type string + local actorName = actorObject:Name() + + ---@type combat + local combatObject = spellsTab.GetCombat() + ---@type instance + local instanceObject = spellsTab.GetInstance() + + local keyToSort = scrollFrame.SortKey + local orderToSort = scrollFrame.SortKey + local headerTable = spellsTab.spellsHeaderData + + --todo: when swapping sort orders, close already expanded spells + + local lineIndex = 1 + for i = 1, totalLines do + local index = i + offset + + ---@type spelltableadv + local bkSpellData = scrollData[index] + + if (bkSpellData) then + ---@type number + local spellTablesAmount = #bkSpellData.nestedData + + ---called mainSpellBar because it is the line that shows the sum of all spells merged (if any) + ---@type breakdownspellbar + local mainSpellBar = getSpellBar(scrollFrame, lineIndex) + do + --main line of the spell, where the sum of all spells merged is shown + if (mainSpellBar) then + lineIndex = lineIndex + 1 + local bIsMainLine = true + local bIsActorHeader = bkSpellData.bIsActorHeader + local spellTableIndex = 1 + local spellBar = mainSpellBar + + local nameToUse = actorName + if (bIsActorHeader) then + nameToUse = bkSpellData.actorName + end + + ---@debug both calls are equal but the traceback will be different in case of an error + if (bIsActorHeader) then + updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) + else + --here + updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) + end + end + end + + --if the spell is expanded + --then it adds the lines for each spell merged, but it cannot use the bkSpellData, it needs the spellTable, it's kinda using bkSpellData, need to debug + if (bkSpellData.bIsExpanded and (spellTablesAmount > 1)) then + --filling necessary information to sort the data by the selected header column + for spellTableIndex = 1, spellTablesAmount do + ---@type bknesteddata + local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex] + ---@type spelltable + local spellTable = nestedBkSpellData.spellTable + nestedBkSpellData.value = spellTable[keyToSort] or getValueForHeaderSortKey(combatObject, spellTable, keyToSort) + end + + --sort the nested data + if (orderToSort == "DESC") then + table.sort(bkSpellData.nestedData, + function(t1, t2) + return t1.value < t2.value + end) + else + table.sort(bkSpellData.nestedData, + function(t1, t2) + return t1.value > t2.value + end) + end + + for spellTableIndex = 1, spellTablesAmount do + ---@type breakdownspellbar + local spellBar = getSpellBar(scrollFrame, lineIndex) + if (spellBar) then + ---@type bknesteddata + local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex] + + lineIndex = lineIndex + 1 + ---@type string + local petName = nestedBkSpellData.actorName + ---@type string + local nameToUse = petName ~= "" and petName or actorName + local bIsMainLine = false + + bkSpellData[keyToSort] = nestedBkSpellData.value + + updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) + mainSpellBar.ExpandedChildren[#mainSpellBar.ExpandedChildren + 1] = spellBar + end + end + end + + if (lineIndex > totalLines) then + break + end + end + end +end + + +---creates a scrollframe which show breakdownspellbar to show the spells used by an actor +---@param tabFrame tabframe +---@return breakdownspellscrollframe +function spellsTab.CreateSpellScrollContainer(tabFrame) --~scroll ~create ~spell ~container ~createspellcontainer + ---@type width + local width = Details.breakdown_spell_tab.spellcontainer_width + ---@type height + local height = Details.breakdown_spell_tab.spellcontainer_height + + local options = { + width = Details.breakdown_spell_tab.spellcontainer_width, + height = Details.breakdown_spell_tab.spellcontainer_height, + is_locked = Details.breakdown_spell_tab.spellcontainer_islocked, + can_move = false, + can_move_children = false, + use_bottom_resizer = true, + use_right_resizer = false, + } + + ---create a container for the scrollframe + ---@type df_framecontainer + local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer") + container:SetPoint("topleft", tabFrame, "topleft", 5, -5) + container:SetFrameLevel(tabFrame:GetFrameLevel() + 10) + spellsTab.SpellContainerFrame = container + + --when a setting is changed in the container, it will call this function, it is registered below with SetSettingChangedCallback() + local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue) --doing here the callback for thge settings changed in the container + if (frameContainer:IsShown()) then + if (settingName == "height") then + ---@type number + local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight() + Details.breakdown_spell_tab.spellcontainer_height = settingValue + spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1) + + elseif (settingName == "width") then + Details.breakdown_spell_tab.spellcontainer_width = settingValue + + elseif (settingName == "is_locked") then + Details.breakdown_spell_tab.spellcontainer_islocked = settingValue + end + + spellsTab.GetSpellBlockContainer():SendSettingChangedCallback("UpdateSize", -1) + end + end + container:SetSettingChangedCallback(settingChangedCallbackFunction) + + --amount of lines which will be created for the scrollframe + local defaultAmountOfLines = 50 + + --replace this with a framework scrollframe + ---@type breakdownspellscrollframe + local scrollFrame = DF:CreateScrollBox(container, "$parentSpellScroll", refreshSpellsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) + DF:ReskinSlider(scrollFrame) + scrollFrame:SetPoint("topleft", container, "topleft", 0, 0) --need to set the points + scrollFrame:SetPoint("bottomright", container, "bottomright", 0, 0) --need to set the points + + container:RegisterChildForDrag(scrollFrame) + + scrollFrame.DontHideChildrenOnPreRefresh = true + tabFrame.SpellScrollFrame = scrollFrame + spellsTab.SpellScrollFrame = scrollFrame + + spellsTab.ApplyStandardBackdrop(container, scrollFrame) + + --~header + local headerOptions = { + padding = 2, + + header_height = 14, + reziser_shown = true, + reziser_width = 2, + reziser_color = {.5, .5, .5, 0.7}, + reziser_max_width = 246, + + header_click_callback = onColumnHeaderClickCallback, + + header_backdrop_color = {0.1, 0.1, 0.1, 0.4}, + text_color = {1, 1, 1, 0.823}, + } + + local headerTable = {} + + ---create the header frame, the header frame is the frame which shows the columns names to describe the data shown in the scrollframe + ---@type df_headerframe + local header = DetailsFramework:CreateHeader(container, headerTable, headerOptions) + scrollFrame.Header = header + scrollFrame.Header:SetPoint("topleft", scrollFrame, "topleft", 0, 1) + scrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged) + + --cache the containerType which this header is used for + headerContainerType[scrollFrame.Header] = "spells" + + --create the scroll lines + for i = 1, defaultAmountOfLines do + scrollFrame:CreateLine(spellsTab.CreateSpellBar) + end + + ---set the data and refresh the scrollframe + ---@param self breakdownspellscrollframe + ---@param data breakdownspelldatalist + function scrollFrame:RefreshMe(data) --~refreshme (spells) ~refreshmes + --get which column is currently selected and the sort order + local columnIndex, order, key = scrollFrame.Header:GetSelectedColumn() + scrollFrame.SortKey = key + scrollFrame.SortOrder = order + + ---@type string + local keyToSort = key + + ---@type combat + local combatObject = spellsTab.GetCombat() + ---@type number, number + local mainAttribute, subAttribute = spellsTab.GetInstance():GetDisplay() + + --filling necessary information to sort the data by the selected header column + for i = 1, #data do + ---@type spelltableadv + local bkSpellData = data[i] + if (not bkSpellData[keyToSort]) then + local value = getValueForHeaderSortKey(combatObject, bkSpellData, keyToSort) + bkSpellData[keyToSort] = value + end + end + + if (order == "DESC") then + table.sort(data, + ---@param t1 spelltableadv + ---@param t2 spelltableadv + function(t1, t2) + return t1[keyToSort] > t2[keyToSort] + end) + self.topValue = data[1] and data[1][keyToSort] + else + table.sort(data, + ---@param t1 spelltableadv + ---@param t2 spelltableadv + function(t1, t2) + return t1[keyToSort] < t2[keyToSort] + end) + self.topValue = data[#data] and data[#data][keyToSort] + end + + self:SetData(data) + self:Refresh() + end + + return scrollFrame +end + + +---create a spellbar within the spell scroll +---@param self breakdownspellscrollframe +---@param index number +---@return breakdownspellbar +function spellsTab.CreateSpellBar(self, index) --~spellbar ~spellline ~spell ~create ~createline ~createspell ~createspellbar + ---@type breakdownspellbar + local spellBar = CreateFrame("button", self:GetName() .. "SpellBarButton" .. index, self) + spellBar.index = index + + --size and positioning + spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT) + local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15 + spellBar:SetPoint("topleft", self, "topleft", 1, y) + spellBar:SetPoint("topright", self, "topright", -1, y) + + spellBar:EnableMouse(true) + spellBar:RegisterForClicks("AnyUp", "AnyDown") + spellBar:SetAlpha(0.823) + spellBar:SetFrameStrata("high") + spellBar:SetScript("OnEnter", onEnterSpellBar) + spellBar:SetScript("OnLeave", onLeaveSpellBar) + spellBar:SetScript("OnMouseDown", onMouseDownBreakdownSpellBar) + spellBar:SetScript("OnMouseUp", onMouseUpBreakdownSpellBar) + spellBar.onMouseUpTime = 0 + spellBar.ExpandedChildren = {} + + DF:Mixin(spellBar, DF.HeaderFunctions) + + ---@type breakdownspellbarstatusbar + local statusBar = CreateFrame("StatusBar", "$parentStatusBar", spellBar) + statusBar:SetAllPoints() + statusBar:SetAlpha(0.5) + statusBar:SetMinMaxValues(0, 100) + statusBar:SetValue(50) + statusBar:EnableMouse(false) + statusBar:SetFrameLevel(spellBar:GetFrameLevel() - 1) + spellBar.statusBar = statusBar + + ---@type texture this is the statusbar texture + local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork") + statusBar:SetStatusBarTexture(statusBarTexture) + statusBar:SetStatusBarColor(1, 1, 1, 1) + + ---@type texture background texture + local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border") + backgroundTexture:SetAllPoints() + statusBar.backgroundTexture = backgroundTexture + + ---@type texture overlay texture to use when the spellbar is selected + local statusBarOverlayTexture = statusBar:CreateTexture("$parentTextureOverlay", "overlay", nil, 7) + statusBarOverlayTexture:SetTexture([[Interface/AddOns/Details/images/overlay_indicator_1]]) + statusBarOverlayTexture:SetVertexColor(1, 1, 1, 0.2) + statusBarOverlayTexture:SetAllPoints() + statusBarOverlayTexture:Hide() + spellBar.overlayTexture = statusBarOverlayTexture + statusBar.overlayTexture = statusBarOverlayTexture + + ---@type texture shown when the mouse hoverover this spellbar + local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight") + hightlightTexture:SetColorTexture(1, 1, 1, 0.2) + hightlightTexture:SetAllPoints() + statusBar.highlightTexture = hightlightTexture + + --button to expand the bar when there's spells merged + ---@type breakdownexpandbutton + local expandButton = CreateFrame("button", "$parentExpandButton", spellBar, "BackdropTemplate") + expandButton:SetSize(CONST_BAR_HEIGHT, CONST_BAR_HEIGHT) + expandButton:RegisterForClicks("LeftButtonDown") + spellBar.expandButton = expandButton + + ---@type texture + local expandButtonTexture = expandButton:CreateTexture("$parentTexture", "artwork") + expandButtonTexture:SetPoint("center", expandButton, "center", 0, 0) + expandButtonTexture:SetSize(CONST_BAR_HEIGHT-2, CONST_BAR_HEIGHT-2) + expandButton.texture = expandButtonTexture + + --frame which will show the spell tooltip + ---@type frame + local spellIconFrame = CreateFrame("frame", "$parentIconFrame", spellBar, "BackdropTemplate") + spellIconFrame:SetSize(CONST_BAR_HEIGHT - 2, CONST_BAR_HEIGHT - 2) + spellIconFrame:SetScript("OnEnter", onEnterSpellIconFrame) + spellIconFrame:SetScript("OnLeave", onLeaveSpellIconFrame) + spellBar.spellIconFrame = spellIconFrame + + --create the icon to show the spell texture + ---@type texture + local spellIcon = spellIconFrame:CreateTexture("$parentTexture", "overlay") + spellIcon:SetAllPoints() + spellIcon:SetTexCoord(.1, .9, .1, .9) + spellBar.spellIcon = spellIcon + + --create a square frame which is placed at the right side of the line to show which targets for damaged by the spell + ---@type breakdowntargetframe + local targetsSquareFrame = CreateFrame("frame", "$parentTargetsFrame", statusBar, "BackdropTemplate") + targetsSquareFrame:SetSize(CONST_SPELLSCROLL_LINEHEIGHT, CONST_SPELLSCROLL_LINEHEIGHT) + targetsSquareFrame:SetAlpha(.7) + targetsSquareFrame:SetScript("OnEnter", onEnterSpellTarget) + targetsSquareFrame:SetScript("OnLeave", onLeaveSpellTarget) + targetsSquareFrame:SetFrameLevel(statusBar:GetFrameLevel()+2) + spellBar.targetsSquareFrame = targetsSquareFrame + + ---@type texture + local targetTexture = targetsSquareFrame:CreateTexture("$parentTexture", "overlay") + targetTexture:SetTexture(CONST_TARGET_TEXTURE) + targetTexture:SetAllPoints() + targetTexture:SetDesaturated(true) + spellBar.targetsSquareTexture = targetTexture + targetsSquareFrame.texture = targetTexture + + spellBar:AddFrameToHeaderAlignment(spellIconFrame) + spellBar:AddFrameToHeaderAlignment(targetsSquareFrame) + + --create texts + ---@type fontstring[] + spellBar.InLineTexts = {} + + for i = 1, 16 do + ---@type fontstring + local fontString = spellBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall") + fontString:SetJustifyH("left") + fontString:SetTextColor(1, 1, 1, 1) + fontString:SetNonSpaceWrap(true) + fontString:SetWordWrap(false) + spellBar["lineText" .. i] = fontString + spellBar.InLineTexts[i] = fontString + fontString:SetTextColor(1, 1, 1, 1) + spellBar:AddFrameToHeaderAlignment(fontString) + end + + spellBar:AlignWithHeader(self.Header, "left") + return spellBar +end diff --git a/frames/window_breakdown/breakdown_spells_targetframes.lua b/frames/window_breakdown/breakdown_spells_targetframes.lua new file mode 100644 index 00000000..7f230444 --- /dev/null +++ b/frames/window_breakdown/breakdown_spells_targetframes.lua @@ -0,0 +1,15 @@ + +local addonName, Details222 = ... +local breakdownWindow = Details.BreakdownWindow +local Loc = LibStub("AceLocale-3.0"):GetLocale("Details") +local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") +local unpack = unpack +local GetTime = GetTime +local CreateFrame = CreateFrame +local GetSpellLink = GetSpellLink +local GetSpellInfo = GetSpellInfo +local _GetSpellInfo = Details.GetSpellInfo +local GameTooltip = GameTooltip +local IsShiftKeyDown = IsShiftKeyDown +local DF = DetailsFramework +local tinsert = tinsert \ No newline at end of file diff --git a/frames/window_playerbreakdown.lua b/frames/window_breakdown/window_playerbreakdown.lua similarity index 100% rename from frames/window_playerbreakdown.lua rename to frames/window_breakdown/window_playerbreakdown.lua index e93b9732..69745bb8 100644 --- a/frames/window_playerbreakdown.lua +++ b/frames/window_breakdown/window_playerbreakdown.lua @@ -97,10 +97,6 @@ function Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttribute ---@type number, number local mainAttribute, subAttribute = instanceObject:GetDisplay() - --create the player list frame in the left side of the window - Details.PlayerBreakdown.CreatePlayerListFrame() - Details.PlayerBreakdown.CreateDumpDataFrame() - if (not Details.row_singleclick_overwrite[mainAttribute] or not Details.row_singleclick_overwrite[mainAttribute][subAttribute]) then Details:CloseBreakdownWindow() return @@ -129,6 +125,10 @@ function Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttribute return end + --create the player list frame in the left side of the window + Details.PlayerBreakdown.CreatePlayerListFrame() + Details.PlayerBreakdown.CreateDumpDataFrame() + if (not breakdownWindow.bHasInitialized) then local infoNumPoints = breakdownWindow:GetNumPoints() for i = 1, infoNumPoints do diff --git a/frames/window_playerbreakdown_auras.lua b/frames/window_breakdown/window_playerbreakdown_auras.lua similarity index 100% rename from frames/window_playerbreakdown_auras.lua rename to frames/window_breakdown/window_playerbreakdown_auras.lua diff --git a/frames/window_playerbreakdown_avoidance.lua b/frames/window_breakdown/window_playerbreakdown_avoidance.lua similarity index 100% rename from frames/window_playerbreakdown_avoidance.lua rename to frames/window_breakdown/window_playerbreakdown_avoidance.lua diff --git a/frames/window_playerbreakdown_charts b/frames/window_breakdown/window_playerbreakdown_charts similarity index 100% rename from frames/window_playerbreakdown_charts rename to frames/window_breakdown/window_playerbreakdown_charts diff --git a/frames/window_playerbreakdown_compare.lua b/frames/window_breakdown/window_playerbreakdown_compare.lua similarity index 100% rename from frames/window_playerbreakdown_compare.lua rename to frames/window_breakdown/window_playerbreakdown_compare.lua diff --git a/frames/window_playerbreakdown_list.lua b/frames/window_breakdown/window_playerbreakdown_list.lua similarity index 100% rename from frames/window_playerbreakdown_list.lua rename to frames/window_breakdown/window_playerbreakdown_list.lua diff --git a/frames/window_playerbreakdown_spells.lua b/frames/window_breakdown/window_playerbreakdown_spells.lua similarity index 57% rename from frames/window_playerbreakdown_spells.lua rename to frames/window_breakdown/window_playerbreakdown_spells.lua index bc7dae3a..ef82772d 100644 --- a/frames/window_playerbreakdown_spells.lua +++ b/frames/window_breakdown/window_playerbreakdown_spells.lua @@ -29,11 +29,6 @@ local iconTableSummary = { height = 16, } -local spellBlockContainerSettings = { - amount = 6, --amount of block the container have - lineAmount = 3, --amount of line each block have -} - local CONST_BAR_HEIGHT = 20 local CONST_SPELLSCROLL_LINEHEIGHT = 20 local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]] @@ -97,12 +92,12 @@ function spellsTab.GetTargetScrollFrame() return spellsTab.TargetScrollFrame end ----@return breakdowntargetscrollframe +---@return breakdownphasescrollframe function spellsTab.GetPhaseScrollFrame() return spellsTab.PhaseScrollFrame end ----@return breakdowntargetscrollframe +---@return breakdowngenericscrollframe function spellsTab.GetGenericScrollFrame() return spellsTab.GenericScrollFrame end @@ -161,6 +156,7 @@ end ---store the header object has key and its type as value, the header type can be 'spell' or 'target' ---@type table local headerContainerType = {} +spellsTab.headerContainerType = headerContainerType ---@type number local columnOffset = 0 @@ -277,7 +273,7 @@ end ---@param optionName string ---@param columnName string ---@param value any -local onHeaderColumnOptionChanged = function(headerFrame, optionName, columnName, value) +function spellsTab.OnHeaderColumnOptionChanged(headerFrame, optionName, columnName, value) ---@type "spells"|"targets"|"phases"|"generic" local containerType = headerContainerType[headerFrame] ---@type headercolumndatabase @@ -287,20 +283,6 @@ local onHeaderColumnOptionChanged = function(headerFrame, optionName, columnName spellsTab.UpdateHeadersSettings(containerType) end ----run when the user clicks the columnHeader ----@param headerFrame df_headerframe ----@param columnHeader df_headercolumnframe -local onColumnHeaderClickCallback = function(headerFrame, columnHeader) - ---@type string - local containerType = headerContainerType[headerFrame] - - local scrollFrame = spellsTab.GetScrollFrameByContainerType(containerType) - scrollFrame:Refresh() - - local instance = spellsTab.GetInstance() - instance:RefreshWindow(true) -end - local onAnyColumnHeaderClickCallback = function() local instance = spellsTab.GetInstance() instance:RefreshWindow(true) @@ -434,33 +416,6 @@ function spellsTab.BuildHeaderTable(containerType) return headerTable end ----some values required by the header sort key is not available in the spellTable, so they need to be calculated ----@param combatObject combat ----@param spellData spelltable|spelltableadv ----@param key string ----@return any -local getValueForHeaderSortKey = function(combatObject, spellData, key) - if (key == "critpercent") then - return Details.SpellTableMixin.GetCritPercent(spellData) - - elseif (key == "casts") then - local spellName = GetSpellInfo(spellData.id) - local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName) - return amountOfCasts - - elseif (key == "castavg") then - local spellName = GetSpellInfo(spellData.id) - local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName) - return Details.SpellTableMixin.GetCastAverage(spellData, amountOfCasts) - - elseif (key == "uptime") then - return combatObject:GetSpellUptime(spellsTab.GetActor():Name(), spellData.id) - - elseif (key == "healabsorbed") then - return spellData.absorbed - end -end - ------------------------------------------------------------------------------------------------------------------------------------------------ --Bar Selection @@ -569,647 +524,10 @@ function spellsTab.OnCreateTabCallback(tabButton, tabFrame) --~init end --------------------------------------------------------------------------------------------------- ---Scripts +--Targets ---create a details bar on the right side of the window -local onEnterSpellBlock = function(spellBlock) --info background is the 6 bars in the right side of the window? - spellBlock.overlay:Show() - spellBlock.reportButton:Show() -end -local onLeaveSpellBlock = function(spellBlock) - spellBlock.overlay:Hide() - spellBlock.reportButton:Hide() -end - -local onEnterInfoReport = function(self) - Details.FadeHandler.Fader(self:GetParent().overlay, 0) - Details.FadeHandler.Fader(self, 0) -end - -local onLeaveInfoReport = function(self) - Details.FadeHandler.Fader(self:GetParent().overlay, 1) - Details.FadeHandler.Fader(self, 1) -end - ----run this function when the mouse hover over a breakdownspellbar ----@param spellBar breakdownspellbar ----@param motion boolean|nil -local onEnterSpellBar = function(spellBar, motion) --parei aqui: precisa por nomes nas funções e formatar as linhas das funcções - --all values from spellBar are cached values - --check if there's a spellbar selected, if there's one, ignore the mouseover - if (spellsTab.HasSelectedSpellBar() and motion) then - return - end - - spellsTab.currentSpellBar = spellBar - - ---@type instance - local instance = spellsTab.GetInstance() - - ---@type combat - local combatObject = spellsTab.GetCombat() - - ---@type number, number - local mainAttribute, subAttribute = instance:GetDisplay() - - ---@type breakdownspellblockframe - local spellBlockContainer = spellsTab.GetSpellBlockFrame() - spellBlockContainer:ClearBlocks() - - ---@type number - local spellId = spellBar.spellId - - ---@type number - local elapsedTime = spellBar.combatTime --this should be actorObject:Tempo() - - ---@type string - local actorName = spellsTab.GetActor():Name() - - ---@type spelltable - local spellTable = spellBar.spellTable - - if (IsShiftKeyDown()) then - if (type(spellId) == "number") then - GameCooltip:Preset(2) - GameCooltip:SetOwner(spellBar) - GameCooltip:AddLine(Loc ["ABILITY_ID"] .. ": " .. spellBar.spellId) - GameCooltip:Show() - - ---@type spelltable - local thisSpellTable = combatObject:GetActor(mainAttribute, actorName).spells._ActorTable[spellId] - - local textToEditor = "" - for key, value in pairs(thisSpellTable) do - if (type(value) ~= "function" and type(value) ~= "table") then - textToEditor = textToEditor .. key .. " = " .. tostring(value) .. "\n" - end - end - - breakdownWindow.dumpDataFrame:Show() - breakdownWindow.dumpDataFrame.luaEditor:SetText(textToEditor) - --hide the scroll bar - _G["DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar"]:Hide() - end - - elseif (breakdownWindow.dumpDataFrame:IsShown()) then - breakdownWindow.dumpDataFrame:Hide() - end - - if (spellId == 98021) then --spirit link totem - GameTooltip:SetOwner(spellBar, "ANCHOR_TOPLEFT") - GameTooltip:AddLine(Loc ["STRING_SPIRIT_LINK_TOTEM_DESC"]) - GameTooltip:Show() - end - - ---@type trinketdata - local trinketData = Details:GetTrinketData() - - ---@type number - local blockIndex = 1 - - --get the first spell block to use as summary - ---@type breakdownspellblock - local summaryBlock = spellBlockContainer:GetBlock(blockIndex) - summaryBlock:Show() - summaryBlock:SetValue(50) - summaryBlock:SetValue(100) - - if (mainAttribute == DETAILS_ATTRIBUTE_DAMAGE) then - --bounce to damage class to handle the spell details - if (subAttribute == 1 or subAttribute == 2 or subAttribute == 6) then - Details.atributo_damage:BuildSpellDetails(spellBar, spellBlockContainer, blockIndex, summaryBlock, spellId, elapsedTime, actorName, spellTable, trinketData, combatObject) - end - - --need to know how many blocks the damage class used - local blocksInUse = spellBlockContainer:GetBlocksInUse() - local maxBlocks = spellBlockContainer:GetBlocksAmount() - - for i = blocksInUse + 1, math.min(maxBlocks, 4) do --in the current state of the breakdown, showing 5 will overlap with the phase container - spellBlockContainer:ShowEmptyBlock(i) - end - - elseif (mainAttribute == DETAILS_ATTRIBUTE_HEAL) then --this should run within the heal class ~healing - ---@type number - local totalHits = spellTable.counter - - --healing section showing healing done sub section - blockIndex = blockIndex + 1 - - do --update the texts in the summary block - local blockLine1, blockLine2, blockLine3 = summaryBlock:GetLines() - - local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or "(?)" - blockLine1.leftText:SetText(Loc ["STRING_CAST"] .. ": " .. totalCasts) --total amount of casts - blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime - - blockLine2.leftText:SetText(Loc ["STRING_HEAL"]..": " .. Details:Format(spellTable.total)) --total damage - blockLine2.rightText:SetText(Details:GetSpellSchoolFormatedName(spellTable.spellschool)) --spell school - - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:Format(spellBar.average)) --average damage - blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps - end - - --check if there's normal hits and build the block - ---@type number - local normalHitsAmt = spellTable.n_amt - - if (normalHitsAmt > 0) then - ---@type breakdownspellblock - local normalHitsBlock = spellBlockContainer:GetBlock(blockIndex) - normalHitsBlock:Show() - blockIndex = blockIndex + 1 - - local percent = normalHitsAmt / math.max(totalHits, 0.0001) * 100 - normalHitsBlock:SetValue(percent) - normalHitsBlock.sparkTexture:SetPoint("left", normalHitsBlock, "left", percent / 100 * normalHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) - - local blockLine1, blockLine2, blockLine3 = normalHitsBlock:GetLines() - blockLine1.leftText:SetText(Loc ["STRING_NORMAL_HITS"]) - blockLine1.rightText:SetText(normalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", normalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") - - blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_min)) - blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_max)) - - local normalAverage = spellTable.n_total / math.max(normalHitsAmt, 0.0001) - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(normalAverage)) - - local tempo = (elapsedTime * spellTable.n_total) / math.max(spellTable.total, 0.001) - local normalAveragePercent = spellBar.average / normalAverage * 100 - local normalTempoPercent = normalAveragePercent * tempo / 100 - blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellTable.n_total / normalTempoPercent)) - end - - ---@type number - local criticalHitsAmt = spellTable.c_amt - if (criticalHitsAmt > 0) then - ---@type breakdownspellblock - local critHitsBlock = spellBlockContainer:GetBlock(blockIndex) - critHitsBlock:Show() - blockIndex = blockIndex + 1 - - local percent = criticalHitsAmt / math.max(totalHits, 0.0001) * 100 - critHitsBlock:SetValue(percent) - critHitsBlock.sparkTexture:SetPoint("left", critHitsBlock, "left", percent / 100 * critHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) - - local blockLine1, blockLine2, blockLine3 = critHitsBlock:GetLines() - blockLine1.leftText:SetText(Loc ["STRING_CRITICAL_HITS"]) - blockLine1.rightText:SetText(criticalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", criticalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") - - blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_min)) - blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_max)) - - local critAverage = spellTable.c_total / math.max(criticalHitsAmt, 0.0001) - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage)) - - local tempo = (elapsedTime * spellTable.c_total) / math.max(spellTable.total, 0.001) - local critAveragePercent = spellBar.average / critAverage * 100 - local critTempoPercent = critAveragePercent * tempo / 100 - blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(spellTable.c_total / critTempoPercent)) - end - - ---@type number - local overheal = spellTable.overheal or 0 - if (overheal > 0) then - --blockIndex = blockIndex + 1 --skip one block - ---@type breakdownspellblock - local overhealBlock = spellBlockContainer:GetBlock(blockIndex) - overhealBlock:Show() - blockIndex = blockIndex + 1 - - local blockName - if (spellTable.is_shield) then - blockName = Loc ["STRING_SHIELD_OVERHEAL"] - else - blockName = Loc ["STRING_OVERHEAL"] - end - - local percent = overheal / (overheal + spellTable.total) * 100 - overhealBlock:SetValue(percent) - overhealBlock.sparkTexture:SetPoint("left", overhealBlock, "left", percent / 100 * overhealBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) - - overhealBlock:SetColor(1, 0, 0, 0.4) - - local blockLine1, blockLine2, blockLine3 = overhealBlock:GetLines() - blockLine1.leftText:SetText(blockName) - - local overhealString = Details:CommaValue(overheal) - local overhealText = overhealString .. " / " .. string.format("%.1f", percent) .. "%" - blockLine1.rightText:SetText(overhealText) - end - end - - --effects on entering the bar line - spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT + 1) - spellBar:SetAlpha(1) - spellBar.spellIcon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT + 2, CONST_SPELLSCROLL_LINEHEIGHT + 2) - spellBar.spellIcon:SetAlpha(1) -end - ----run this function when the mouse leaves a breakdownspellbar ----@param spellBar breakdownspellbar -local onLeaveSpellBar = function(spellBar) - spellsTab.currentSpellBar = nil - - --remove effects on entering the bar line - spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT) - spellBar:SetAlpha(0.9) - - GameTooltip:Hide() - GameCooltip:Hide() - - --clear spell blocks - if (not spellsTab.HasSelectedSpellBar()) then - spellsTab.GetSpellBlockFrame():ClearBlocks() - end - - if (breakdownWindow.dumpDataFrame:IsShown()) then - breakdownWindow.dumpDataFrame:Hide() - end -end - ----on mouse down a breakdownspellbar in the breakdown window ----@param spellBar breakdownspellbar ----@param button string -local onMouseDownBreakdownSpellBar = function(spellBar, button) - local x, y = _G.GetCursorPosition() - spellBar.cursorPosX = math.floor(x) - spellBar.cursorPosY = math.floor(y) -end - ----on mouse up a breakdownspellbar in the breakdown window ----@param spellBar breakdownspellbar ----@param button string -local onMouseUpBreakdownSpellBar = function(spellBar, button) - spellBar.onMouseUpTime = GetTime() - - ---@type number, number - local x, y = _G.GetCursorPosition() - x = math.floor(x) - y = math.floor(y) - - ---@type boolean - local bIsMouseInTheSamePosition = (x == spellBar.cursorPosX) and (y == spellBar.cursorPosY) - - --if the mouse is in the same position, then the user clicked the bar - if (bIsMouseInTheSamePosition) then - spellsTab.SelectSpellBar(spellBar) - end -end - -local onEnterSpellIconFrame = function(self) - local line = self:GetParent() - if (line.spellId and type(line.spellId) == "number") then - local spellName = _GetSpellInfo(line.spellId) - if (spellName) then - GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT") - Details:GameTooltipSetSpellByID(line.spellId) - GameTooltip:Show() - end - end - line:GetScript("OnEnter")(line) -end - -local onLeaveSpellIconFrame = function(self) - GameTooltip:Hide() - self:GetParent():GetScript("OnLeave")(self:GetParent()) -end - --------------------------------------------------------------------------------------------------------------------------------------------- ---Spell Blocks - -local spellBlockMixin = { - ---get one of the three lines containing fontstrings to show data - ---line 1 is the top line, line 2 is the middle line and line 3 is the bottom line - ---@param self breakdownspellblock - ---@param lineIndex number - ---@return breakdownspellblockline - GetLine = function(self, lineIndex) - ---@type breakdownspellblockline - local line = self.Lines[lineIndex] - return line - end, - - ---return all lines in the spell block, all spell block have 3 lines - ---@param self breakdownspellblock - ---@return breakdownspellblockline, breakdownspellblockline, breakdownspellblockline - GetLines = function(self) - return unpack(self.Lines) - end, - - ---@param self breakdownspellblock - SetColor = function(self, ...) - local r, g, b, a = DF:ParseColors(...) - self.statusBarTexture:SetColorTexture(r, g, b, a) - end, -} - ----create a spell block into the spellblockcontainer ----@param spellBlockContainer breakdownspellblockframe ----@param index number ----@return breakdownspellblock -function spellsTab.CreateSpellBlock(spellBlockContainer, index) --~breakdownspellblock ~create ~spellblocks - ---@type breakdownspellblock - local spellBlock = CreateFrame("statusbar", "$parentBlock" .. index, spellBlockContainer, "BackdropTemplate") - DetailsFramework:Mixin(spellBlock, spellBlockMixin) - - local statusBarTexture = spellBlock:CreateTexture("$parentTexture", "artwork") - statusBarTexture:SetColorTexture(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR)) - statusBarTexture:SetPoint("topleft", spellBlock, "topleft", 1, -1) - statusBarTexture:SetPoint("bottomleft", spellBlock, "bottomleft", 1, 1) - spellBlock.statusBarTexture = statusBarTexture - - spellBlock:SetScript("OnEnter", onEnterSpellBlock) - spellBlock:SetScript("OnLeave", onLeaveSpellBlock) - spellBlock:SetScript("OnValueChanged", function() - statusBarTexture:SetWidth(spellBlock:GetValue() / 100 * spellBlock:GetWidth()) - end) - - spellBlock:SetMinMaxValues(0, 100) - spellBlock:SetValue(100) - - --set the backdrop to have a 8x8 edge file - spellsTab.ApplyStandardBackdrop(spellBlock) - - --create the lines which will host the texts - spellBlock.Lines = {} - for i = 1, spellBlockContainerSettings.lineAmount do - ---@type breakdownspellblockline - local line = CreateFrame("frame", "$parentLine" .. i, spellBlock) - spellBlock.Lines[i] = line - - line.leftText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") - line.centerText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") - line.rightText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall") - - line.leftText:SetPoint("left", line, "left", 2, 0) - line.leftText:SetJustifyH("left") - line.centerText:SetPoint("center", line, "center", 0, 0) - line.centerText:SetJustifyH("center") - line.rightText:SetPoint("right", line, "right", -2, 0) - line.rightText:SetJustifyH("right") - end - - --overlay texture which fade in and out when the spell block is hovered over - --is only possible to hover over a spell block when the spellbar is selected - spellBlock.overlay = spellBlock:CreateTexture("$parentOverlay", "artwork") - spellBlock.overlay:SetTexture("Interface\\AddOns\\Details\\images\\overlay_detalhes") - spellBlock.overlay:SetPoint("topleft", spellBlock, "topleft", -8, 8) - spellBlock.overlay:SetPoint("bottomright", spellBlock, "bottomright", 26, -14) - Details.FadeHandler.Fader(spellBlock.overlay, 1) --hide - - --report button, also only shown when the spell block is hovered over - spellBlock.reportButton = Details.gump:NewDetailsButton(spellBlock, nil, nil, Details.Reportar, Details.playerDetailWindow, 10 + index, 16, 16, - "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", nil, "DetailsJanelaInfoReport1") - Details.FadeHandler.Fader(spellBlock.reportButton, 1) --hide - spellBlock.reportButton:SetScript("OnEnter", onEnterInfoReport) - spellBlock.reportButton:SetScript("OnLeave", onLeaveInfoReport) - - --spark texture - spellBlock.sparkTexture = spellBlock:CreateTexture("$parentOverlaySparkTexture", "overlay") - spellBlock.sparkTexture:SetTexture("Interface\\AddOns\\Details\\images\\bar_detalhes2_end") - spellBlock.sparkTexture:SetBlendMode("ADD") - - local gradientDown = DetailsFramework:CreateTexture(spellBlock, {gradient = "vertical", fromColor = {0, 0, 0, 0.1}, toColor = "transparent"}, 1, spellBlock:GetHeight(), "background", {0, 1, 0, 1}) - gradientDown:SetPoint("bottoms") - spellBlock.gradientTexture = gradientDown - spellBlock.gradientTexture:Hide() - - return spellBlock -end - -local spellBlockContainerMixin = { - ---refresh all the spellblocks in the container ~UpdateBlocks - ---this function adjust the frame properties, does not update the data shown on them - ---@param self breakdownspellblockframe - UpdateBlocks = function(self) --~update - ---@type number, number - local width, height = Details.breakdown_spell_tab.blockcontainer_width, Details.breakdown_spell_tab.blockcontainer_height - local blockHeight = Details.breakdown_spell_tab.blockspell_height - local backgroundColor = Details.breakdown_spell_tab.blockspell_backgroundcolor - local borderColor = Details.breakdown_spell_tab.blockspell_bordercolor - local padding = Details.breakdown_spell_tab.blockspell_padding * -1 - local color = Details.breakdown_spell_tab.blockspell_color - - self:SetSize(width, height) - - backgroundColor[1], backgroundColor[2], backgroundColor[3], backgroundColor[4] = 0.05, 0.05, 0.05, 0.2 - color[1], color[2], color[3], color[4] = 0.6, 0.6, 0.6, 0.55 - - for i = 1, #self.SpellBlocks do - ---@type breakdownspellblock - local spellBlock = self.SpellBlocks[i] - - spellBlock:SetSize(width - 2, blockHeight) - spellBlock:SetPoint("topleft", self, "topleft", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding)) - spellBlock:SetPoint("topright", self, "topright", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding)) - - spellBlock.sparkTexture:SetSize(Details.breakdown_spell_tab.blockspell_spark_width, blockHeight) - spellBlock.sparkTexture:SetShown(Details.breakdown_spell_tab.blockspell_spark_show) - spellBlock.sparkTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_spark_color)) - spellBlock.reportButton:SetPoint("bottomright", spellBlock.overlay, "bottomright", -2, 2) - spellBlock.gradientTexture:SetHeight(blockHeight) - - spellBlock:SetBackdropBorderColor(unpack(borderColor)) --border color - spellBlock.statusBarTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_color)) --bar color - - local lineHeight = blockHeight * 0.2687 - - --update the lines - local previousLine - for o = 1, spellBlockContainerSettings.lineAmount do - ---@type breakdownspellblockline - local line = spellBlock.Lines[o] - line:SetSize(width - 2, lineHeight) - if (previousLine) then - line:SetPoint("topleft", previousLine, "bottomleft", 0, -2) - else - line:SetPoint("topleft", spellBlock, "topleft", 1, -2) - end - previousLine = line - end - end - end, - - ---@param self breakdownspellblockframe - ClearBlocks = function(self) - for i = 1, self:GetBlocksAmount() do - ---@type breakdownspellblock - local spellBlock = self.SpellBlocks[i] - spellBlock:Hide() - - spellBlock:SetColor(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR)) - - --set the status bar value to zero - spellBlock:SetValue(0) - spellBlock.statusBarTexture:Show() - spellBlock.sparkTexture:Show() - - --clear the text shown in their lines - for o = 1, 3 do - spellBlock.Lines[o].leftText:SetText("") - - --set the color of the top left text in the block, the text is used as header text - if (o == 1) then - DF:SetFontColor(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_COLOR) - DF:SetFontSize(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_SIZE) - end - - spellBlock.Lines[o].centerText:SetText("") - spellBlock.Lines[o].rightText:SetText("") - end - end - - for i = 1, math.min(self:GetBlocksAmount(), 4) do - self:ShowEmptyBlock(i) - end - - self.blocksInUse = 0 - end, - - ---show the empty block in the container, this is done to preview where the rectangle will be - ---@param self breakdownspellblockframe - ---@param index number - ShowEmptyBlock = function(self, index) - local spellBlock = self.SpellBlocks[index] - spellBlock:Show() - spellBlock:SetValue(0) - spellBlock.statusBarTexture:Hide() - spellBlock.sparkTexture:Hide() - end, - - ---get a breakdownspellblock from the container - ---@param self breakdownspellblockframe - ---@param index number - ---@return breakdownspellblock - GetBlock = function(self, index) - self.blocksInUse = self.blocksInUse + 1 - local spellBlock = self.SpellBlocks[index] - spellBlock.statusBarTexture:Show() - spellBlock.sparkTexture:Show() - return self.SpellBlocks[index] - end, - - ---get the amount of blocks in use - ---@param self breakdownspellblockframe - ---@return number - GetBlocksInUse = function(self) - return self.blocksInUse - end, - - ---get the total blocks created - ---@param self breakdownspellblockframe - ---@return number - GetBlocksAmount = function(self) - return #self.SpellBlocks - end, -} - ----create the spell blocks which shows the critical hits, normal hits, etc ----@param tabFrame tabframe ----@return breakdownspellblockframe -function spellsTab.CreateSpellBlockContainer(tabFrame) --~create ~createblock ~spellblock ~block ~container - --create a container for the scrollframe - local options = { - width = Details.breakdown_spell_tab.blockcontainer_width, - height = Details.breakdown_spell_tab.blockcontainer_height, - is_locked = Details.breakdown_spell_tab.blockcontainer_islocked, - can_move = false, - can_move_children = false, - use_bottom_resizer = true, - use_right_resizer = true, - } - - ---@type df_framecontainer - local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer") - container:SetPoint("topleft", spellsTab.GetSpellScrollContainer(), "topright", 26, 0) - container:SetFrameLevel(tabFrame:GetFrameLevel() + 10) - spellsTab.BlocksContainerFrame = container - - local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue) - if (frameContainer:IsShown()) then - if (settingName == "UpdateSize") then - --get the tabFrame width and height - local width, height = tabFrame:GetSize() - local containerWidth - - --get with of the container holding the spellscrollframe - if (spellsTab.GetSpellScrollContainer():IsShown()) then - containerWidth = spellsTab.GetSpellScrollContainer():GetWidth() - - elseif (spellsTab.GetGenericScrollContainer():IsShown()) then - containerWidth = spellsTab.GetGenericScrollContainer():GetWidth() - end - - --calculate the widh of the spellblockcontainer by subtracting the width of the spellscrollframe container from the tabFrame width - local spellBlockContainerWidth = width - containerWidth - 38 - --set the width of the spellblockcontainer - container:SetWidth(spellBlockContainerWidth) - - elseif (settingName == "height") then - ---@type number - local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight() - Details.breakdown_spell_tab.blockcontainer_height = settingValue - spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1) - - elseif (settingName == "width") then - Details.breakdown_spell_tab.blockcontainer_width = settingValue - - elseif (settingName == "is_locked") then - Details.breakdown_spell_tab.blockcontainer_islocked = settingValue - end - - --update the spell blocks - spellsTab.GetSpellBlockFrame():UpdateBlocks() - - if (spellsTab.GetSelectedSpellBar()) then - onEnterSpellBar(spellsTab.GetSelectedSpellBar()) - end - end - end - container:SetSettingChangedCallback(settingChangedCallbackFunction) - - --create the container which will hold the spell blocks - ---@type breakdownspellblockframe - local spellBlockFrame = CreateFrame("Frame", "$parentSpellBlockContainer", container, "BackdropTemplate") - spellBlockFrame:EnableMouse(false) - spellBlockFrame:SetResizable(false) - spellBlockFrame:SetMovable(false) - spellBlockFrame:SetAllPoints() - DetailsFramework:Mixin(spellBlockFrame, spellBlockContainerMixin) - - tabFrame.SpellBlockFrame = spellBlockFrame - spellsTab.SpellBlockFrame = spellBlockFrame - - container:RegisterChildForDrag(spellBlockFrame) - - spellBlockFrame.SpellBlocks = {} - spellBlockFrame.blocksInUse = 0 - - --create the spell blocks within the spellBlockFrame - for i = 1, spellBlockContainerSettings.amount do - ---@type breakdownspellblock - local spellBlock = spellsTab.CreateSpellBlock(spellBlockFrame, i) - table.insert(spellBlockFrame.SpellBlocks, spellBlock) - --size and point are set on ~UpdateBlocks - end - - spellBlockFrame:UpdateBlocks() - - return spellBlockFrame -end - -function spellsTab.UpdateShownSpellBlock() - if (spellsTab.currentSpellBar) then - onEnterSpellBar(spellsTab.currentSpellBar) - - elseif (spellsTab.GetSelectedSpellBar()) then - onEnterSpellBar(spellsTab.GetSelectedSpellBar()) - end - -end - ----get a spell bar from the scroll box, if it doesn't exist, return nil +---get a target bar from the scroll box, if it doesn't exist, return nil ---@param scrollFrame table ---@param lineIndex number ---@return breakdowntargetbar @@ -1471,7 +789,7 @@ function spellsTab.CreatePhaseBar(self, index) --~create ~createphase ~phasebar return phaseBar end ----get a spell bar from the scroll box, if it doesn't exist, return nil +---get a generic bar from the scroll box, if it doesn't exist, return nil ---@param scrollFrame table ---@param lineIndex number ---@return breakdownphasebar @@ -1658,7 +976,7 @@ end ---create a container to show value per phase ---@param tabFrame tabframe ----@return breakdowntargetscrollframe +---@return breakdownphasescrollframe function spellsTab.CreatePhasesContainer(tabFrame) --~phase ~createphasecontainer ~createphasescroll ---@type width local width = Details.breakdown_spell_tab.phasecontainer_width @@ -1705,7 +1023,7 @@ function spellsTab.CreatePhasesContainer(tabFrame) --~phase ~createphasecontaine end container:SetSettingChangedCallback(settingChangedCallbackFunction) - ---@type breakdowntargetscrollframe not sure is this is correct + ---@type breakdownphasescrollframe not sure is this is correct local phaseScrollFrame = DF:CreateScrollBox(container, "$parentPhaseScroll", refreshPhaseFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) DF:ReskinSlider(phaseScrollFrame) @@ -1841,7 +1159,7 @@ function spellsTab.CreatePhasesContainer(tabFrame) --~phase ~createphasecontaine local header = DetailsFramework:CreateHeader(container, phaseContainerColumnData, headerOptions) phaseScrollFrame.Header = header phaseScrollFrame.Header:SetPoint("topleft", phaseScrollFrame, "topleft", 0, 1) - phaseScrollFrame.Header:SetColumnSettingChangedCallback(onHeaderColumnOptionChanged) + phaseScrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged) --cache the type of this container headerContainerType[phaseScrollFrame.Header] = "phases" @@ -1877,8 +1195,8 @@ function spellsTab.CreateGenericBar(self, index) --~create ~generic ~creategener genericBar:SetAlpha(0.9) genericBar:SetFrameStrata("HIGH") - genericBar:SetScript("OnEnter", onEnterBreakdownGenericBar) - genericBar:SetScript("OnLeave", onLeaveBreakdownGenericBar) + genericBar:SetScript("OnEnter", nil) --onEnterBreakdownGenericBar + genericBar:SetScript("OnLeave", nil) --onLeaveBreakdownGenericBar DF:Mixin(genericBar, DF.HeaderFunctions) @@ -2052,7 +1370,7 @@ function spellsTab.CreateGenericContainer(tabFrame) --~create ~generic ~createge local header = DetailsFramework:CreateHeader(container, genericContainerColumnData, headerOptions) genericScrollFrame.Header = header genericScrollFrame.Header:SetPoint("topleft", genericScrollFrame, "topleft", 0, 1) - genericScrollFrame.Header:SetColumnSettingChangedCallback(onHeaderColumnOptionChanged) + genericScrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged) --cache the type of this container headerContainerType[genericScrollFrame.Header] = "generic" @@ -2185,7 +1503,7 @@ function spellsTab.CreateTargetContainer(tabFrame) --~create ~target ~createtarg local header = DetailsFramework:CreateHeader(container, targetContainerColumnData, headerOptions) targetScrollFrame.Header = header targetScrollFrame.Header:SetPoint("topleft", targetScrollFrame, "topleft", 0, 1) - targetScrollFrame.Header:SetColumnSettingChangedCallback(onHeaderColumnOptionChanged) + targetScrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged) --cache the type of this container headerContainerType[targetScrollFrame.Header] = "targets" @@ -2202,649 +1520,10 @@ function spellsTab.CreateTargetContainer(tabFrame) --~create ~target ~createtarg return targetScrollFrame end ---logistics: class_damage build the list of spells, send it to window_playerbreakdown, which gets the current summary tab and send the data for it ---in this tab, the data is sent to the refresh function -local onClickExpandButton = function(expandButton, button) - ---@type breakdownspellbar - local spellBar = expandButton:GetParent() - ---@type table - local scrolFrame = spellBar:GetParent() - ---@type boolean - local bIsSpellExpaded = expandButton.bIsSpellExpaded - --check if the one of the expanded bars was a selected spellbar and deselect - --get the current selected spellbar - ---@type breakdownspellbar - local selectedSpellBar = spellsTab.GetSelectedSpellBar() - if (bIsSpellExpaded) then --it's already expended, it'll close the expanded spellbars - --check if the selected spellbar is one of the expanded spellbars and deselect it - for i = 1, #spellBar.ExpandedChildren do - ---@type breakdownspellbar - local expandedSpellBar = spellBar.ExpandedChildren[i] - if (expandedSpellBar == selectedSpellBar) then - --deselect the spellbar - spellsTab.UnSelectSpellBar() - break - end - end - else - spellsTab.UnSelectSpellBar() - end - --todo: check is any other bar has expanded state true, and close the expand (or not) - - --toggle this spell expand mode - Details222.BreakdownWindow.SetSpellAsExpanded(expandButton.petName or expandButton.spellId, not bIsSpellExpaded) - - --call the refresh function of the window - ---@type instance - local instanceObject = spellsTab.GetInstance() - instanceObject:RefreshWindow(true) -end - -local formatPetName = function(petName, spellName, ownerName) - --petName is raw (with the owner name) - local petNameWithoutOwner = petName:gsub((" <.*"), "") - - local texture = [[Interface\AddOns\Details\images\classes_small]] - - local bUseAlphaIcons = true - local specIcon = false - local iconSize = 14 - - if (petName:len() == 0) then - return Details:AddClassOrSpecIcon(spellName, "PET", specIcon, iconSize, bUseAlphaIcons) - end - - petNameWithoutOwner = Details:AddClassOrSpecIcon(petNameWithoutOwner, "PET", specIcon, iconSize, bUseAlphaIcons) - - return spellName .. " |cFFCCBBBB" .. petNameWithoutOwner .. "|r" -end - ----update a line using the data passed ----@param spellBar breakdownspellbar ----@param index number spell position (from best to wrost) ----@param actorName string ----@param combatObject combat ----@param scrollFrame table ----@param headerTable table ----@param bkSpellData spelltableadv ----@param spellTableIndex number ----@param totalValue number ----@param topValue number ----@param bIsMainLine boolean if true this is the line which has all the values of the spell merged ----@param sortKey string ----@param spellTablesAmount number -local updateSpellBar = function(spellBar, index, actorName, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, sortKey, spellTablesAmount) - --scrollFrame is defined as a table which is false, scrollFrame is a frame - - local textIndex = 1 - for headerIndex = 1, #headerTable do - ---@type number - local spellId - ---@type number - local value - ---@type spelltable - local spellTable - - spellBar.bkSpellData = bkSpellData - - local petName = "" - ---@type boolean @if true, this is the main line of an actor which has its spells nested in the bkSpellData.nestedData - local bIsActorHeader = bkSpellData.bIsActorHeader - - if (bIsMainLine and bIsActorHeader) then - spellTable = bkSpellData - value = bkSpellData.total - spellId = 0 - petName = actorName - - elseif (bIsMainLine) then - spellTable = bkSpellData - value = bkSpellData.total - spellId = bkSpellData.id - petName = bkSpellData.nestedData[spellTableIndex].actorName - - else - spellTable = bkSpellData.nestedData[spellTableIndex].spellTable - value = spellTable.total - spellId = spellTable.id - - --if isn't a spell from a nested actor, then it can use the pet name in the spell name - if (not bkSpellData.nestedData[spellTableIndex].bIsActorHeader) then - petName = bkSpellData.nestedData[spellTableIndex].actorName - end - - spellBar.bIsExpandedSpell = true - end - - spellBar.spellId = spellId - - ---@cast spellTable spelltable - spellBar.spellTable = spellTable - - ---@type string, number, string - local spellName, _, spellIcon = Details.GetSpellInfo(spellId) - if (not spellName) then - spellName = actorName - spellIcon = bkSpellData.actorIcon or "" - end - - ---@type number - local amtCasts = combatObject:GetSpellCastAmount(actorName, spellName) - spellBar.amountCasts = amtCasts - - ---@type number - local uptime = combatObject:GetSpellUptime(actorName, spellId) - - ---@type number - local combatTime = combatObject:GetCombatTime() - - --statusbar size by percent - if (topValue > 0) then - local barValue = spellTable[sortKey] or getValueForHeaderSortKey(combatObject, spellTable, sortKey) - spellBar.statusBar:SetValue(barValue / topValue * 100) - else - spellBar.statusBar:SetValue(0) - end - - if (petName ~= "") then - --if is a pet spell and has more pets nested || nop, now is a pet with its spells nested - if (spellTablesAmount > 1 and bIsMainLine) then - spellName = formatPetName("", spellName, "") --causing error as spellName is nil - elseif (bIsMainLine) then - spellName = formatPetName(petName, spellName, actorName) - else - spellName = formatPetName(petName, "", "") - end - end - - spellBar.spellId = spellId - spellBar.spellIconFrame.spellId = spellId - - spellBar.statusBar.backgroundTexture:SetAlpha(Details.breakdown_spell_tab.spellbar_background_alpha) - - --statusbar color by school - local r, g, b = Details:GetSpellSchoolColor(spellTable.spellschool or 1) - spellBar.statusBar:SetStatusBarColor(r, g, b, 0.963) - - spellBar.average = value / spellTable.counter - spellBar.combatTime = combatTime - - ---@type fontstring - local text = spellBar.InLineTexts[textIndex] - local header = headerTable[headerIndex] - - if (header.name == "icon") then - spellBar.spellIcon:Show() - spellBar.spellIcon:SetTexture(spellIcon) - spellBar.spellIcon:SetAlpha(0.92) - spellBar:AddFrameToHeaderAlignment(spellBar.spellIconFrame) - - elseif (header.name == "target") then --the tab does not have knownledge about the targets of the spell, it must be passed over - ---@type breakdowntargetframe - local targetsSquareFrame = spellBar.targetsSquareFrame - targetsSquareFrame:Show() - targetsSquareFrame.spellId = spellId - targetsSquareFrame.bkSpellData = spellTable - targetsSquareFrame.spellTable = spellTable - targetsSquareFrame.bIsMainLine = bIsMainLine - spellBar:AddFrameToHeaderAlignment(targetsSquareFrame) - - elseif (header.name == "rank") then - text:SetText(index) - spellBar:AddFrameToHeaderAlignment(text) - spellBar.rank = index - textIndex = textIndex + 1 - - elseif (header.name == "expand") then - text:SetText("") - spellBar:AddFrameToHeaderAlignment(spellBar.expandButton) - textIndex = textIndex + 1 - - if (bkSpellData.bCanExpand and bIsMainLine) then - spellBar.expandButton:Show() - local bIsSpellExpaded = Details222.BreakdownWindow.IsSpellExpanded(bIsActorHeader and actorName or spellId) - spellBar.expandButton.spellId = bIsActorHeader and actorName or spellId - spellBar.expandButton.bIsSpellExpaded = bIsSpellExpaded - spellBar.expandButton:SetScript("OnClick", onClickExpandButton) - - --update the texture taking the state of the expanded value - if (bIsSpellExpaded) then - spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]]) - spellBar.expandButton.texture:SetTexCoord(0, 1, 1, 0) - else - spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]]) - spellBar.expandButton.texture:SetTexCoord(0, 1, 0, 1) - end - - spellBar.expandButton.texture:SetAlpha(0.7) - spellBar.expandButton.texture:SetSize(16, 16) - end - - elseif (header.name == "name") then - text:SetText(Details:RemoveOwnerName(spellName)) - spellBar.name = spellName - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "amount") then - text:SetText(Details:Format(value)) - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "persecond") then - spellBar.perSecond = value / combatTime - - ---@type string - local perSecondFormatted = Details:Format(spellBar.perSecond) - text:SetText(perSecondFormatted) - - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "percent") then - spellBar.percent = value / totalValue * 100 - ---@type string - local percentFormatted = string.format("%.1f", spellBar.percent) .. "%" - text:SetText(percentFormatted) - - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "casts") then - text:SetText(amtCasts) - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "critpercent") then - text:SetText(string.format("%.1f", spellTable.c_amt / (spellTable.counter) * 100) .. "%") - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "hits") then - text:SetText(spellTable.counter) - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "castavg") then - if (amtCasts > 0) then - spellBar.castAverage = value / amtCasts - text:SetText(Details:Format(spellBar.castAverage)) - else - text:SetText("0") - end - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "uptime") then --need to get the uptime of the spell with the biggest uptime - text:SetText(string.format("%.1f", uptime / combatTime * 100) .. "%") - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "overheal" and spellTable.overheal) then - if (spellTable.overheal > 0) then - local totalHeal = spellTable.overheal + value - text:SetText(Details:ToK2(spellTable.overheal) .. " (" .. math.floor(spellTable.overheal / totalHeal * 100) .. "%)") - else - text:SetText("0%") - end - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - - elseif (header.name == "absorbed") then - text:SetText(Details:Format(spellTable.absorbed or 0)) - spellBar:AddFrameToHeaderAlignment(text) - textIndex = textIndex + 1 - end - end - - spellBar:AlignWithHeader(scrollFrame.Header, "left") -end - ----get a spell bar from the scroll box, if it doesn't exist, return nil ----@param scrollFrame table ----@param lineIndex number ----@return breakdownspellbar -local getSpellBar = function(scrollFrame, lineIndex) - ---@type breakdownspellbar - local spellBar = scrollFrame:GetLine(lineIndex) - - spellBar.bIsExpandedSpell = false - - Details:Destroy(spellBar.ExpandedChildren) - - --reset header alignment - spellBar:ResetFramesToHeaderAlignment() - - spellsTab.UpdateBarSettings(spellBar) - - --reset columns, hiding them - spellBar.spellIcon:Hide() - spellBar.expandButton:Hide() - spellBar.targetsSquareFrame:Hide() - for inLineIndex = 1, #spellBar.InLineTexts do - spellBar.InLineTexts[inLineIndex]:SetText("") - end - - return spellBar -end - ----refresh the data shown in the spells scroll box ----@param scrollFrame table ----@param scrollData breakdownspelldatalist ----@param offset number ----@param totalLines number -local refreshSpellsFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshspells ~refreshfunc ~refresh ~refreshs - ---@type number - local topValue = scrollFrame.topValue - ---@type number - local totalValue = scrollData.totalValue - ---@type actor - local actorObject = spellsTab.GetActor() - ---@type string - local actorName = actorObject:Name() - - ---@type combat - local combatObject = spellsTab.GetCombat() - ---@type instance - local instanceObject = spellsTab.GetInstance() - - local keyToSort = scrollFrame.SortKey - local orderToSort = scrollFrame.SortKey - local headerTable = spellsTab.spellsHeaderData - - --todo: when swapping sort orders, close already expanded spells - - local lineIndex = 1 - for i = 1, totalLines do - local index = i + offset - - ---@type spelltableadv - local bkSpellData = scrollData[index] - - if (bkSpellData) then - ---@type number - local spellTablesAmount = #bkSpellData.nestedData - - ---called mainSpellBar because it is the line that shows the sum of all spells merged (if any) - ---@type breakdownspellbar - local mainSpellBar = getSpellBar(scrollFrame, lineIndex) - do - --main line of the spell, where the sum of all spells merged is shown - if (mainSpellBar) then - lineIndex = lineIndex + 1 - local bIsMainLine = true - local bIsActorHeader = bkSpellData.bIsActorHeader - local spellTableIndex = 1 - local spellBar = mainSpellBar - - local nameToUse = actorName - if (bIsActorHeader) then - nameToUse = bkSpellData.actorName - end - - ---@debug both calls are equal but the traceback will be different in case of an error - if (bIsActorHeader) then - updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) - else - --here - updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) - end - end - end - - --if the spell is expanded - --then it adds the lines for each spell merged, but it cannot use the bkSpellData, it needs the spellTable, it's kinda using bkSpellData, need to debug - if (bkSpellData.bIsExpanded and (spellTablesAmount > 1)) then - --filling necessary information to sort the data by the selected header column - for spellTableIndex = 1, spellTablesAmount do - ---@type bknesteddata - local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex] - ---@type spelltable - local spellTable = nestedBkSpellData.spellTable - nestedBkSpellData.value = spellTable[keyToSort] or getValueForHeaderSortKey(combatObject, spellTable, keyToSort) - end - - --sort the nested data - if (orderToSort == "DESC") then - table.sort(bkSpellData.nestedData, - function(t1, t2) - return t1.value < t2.value - end) - else - table.sort(bkSpellData.nestedData, - function(t1, t2) - return t1.value > t2.value - end) - end - - for spellTableIndex = 1, spellTablesAmount do - ---@type breakdownspellbar - local spellBar = getSpellBar(scrollFrame, lineIndex) - if (spellBar) then - ---@type bknesteddata - local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex] - - lineIndex = lineIndex + 1 - ---@type string - local petName = nestedBkSpellData.actorName - ---@type string - local nameToUse = petName ~= "" and petName or actorName - local bIsMainLine = false - - bkSpellData[keyToSort] = nestedBkSpellData.value - - updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount) - mainSpellBar.ExpandedChildren[#mainSpellBar.ExpandedChildren + 1] = spellBar - end - end - end - - if (lineIndex > totalLines) then - break - end - end - end -end - ----creates a scrollframe which show breakdownspellbar to show the spells used by an actor ----@param tabFrame tabframe ----@return breakdownspellscrollframe -function spellsTab.CreateSpellScrollContainer(tabFrame) --~scroll ~create ~spell ~container ~createspellcontainer - ---@type width - local width = Details.breakdown_spell_tab.spellcontainer_width - ---@type height - local height = Details.breakdown_spell_tab.spellcontainer_height - - local options = { - width = Details.breakdown_spell_tab.spellcontainer_width, - height = Details.breakdown_spell_tab.spellcontainer_height, - is_locked = Details.breakdown_spell_tab.spellcontainer_islocked, - can_move = false, - can_move_children = false, - use_bottom_resizer = true, - use_right_resizer = false, - } - - ---create a container for the scrollframe - ---@type df_framecontainer - local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer") - container:SetPoint("topleft", tabFrame, "topleft", 5, -5) - container:SetFrameLevel(tabFrame:GetFrameLevel() + 10) - spellsTab.SpellContainerFrame = container - - --when a setting is changed in the container, it will call this function, it is registered below with SetSettingChangedCallback() - local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue) --doing here the callback for thge settings changed in the container - if (frameContainer:IsShown()) then - if (settingName == "height") then - ---@type number - local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight() - Details.breakdown_spell_tab.spellcontainer_height = settingValue - spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1) - - elseif (settingName == "width") then - Details.breakdown_spell_tab.spellcontainer_width = settingValue - - elseif (settingName == "is_locked") then - Details.breakdown_spell_tab.spellcontainer_islocked = settingValue - end - - spellsTab.GetSpellBlockContainer():SendSettingChangedCallback("UpdateSize", -1) - end - end - container:SetSettingChangedCallback(settingChangedCallbackFunction) - - --amount of lines which will be created for the scrollframe - local defaultAmountOfLines = 50 - - --replace this with a framework scrollframe - ---@type breakdownspellscrollframe - local scrollFrame = DF:CreateScrollBox(container, "$parentSpellScroll", refreshSpellsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) - DF:ReskinSlider(scrollFrame) - scrollFrame:SetPoint("topleft", container, "topleft", 0, 0) --need to set the points - scrollFrame:SetPoint("bottomright", container, "bottomright", 0, 0) --need to set the points - - container:RegisterChildForDrag(scrollFrame) - - scrollFrame.DontHideChildrenOnPreRefresh = true - tabFrame.SpellScrollFrame = scrollFrame - spellsTab.SpellScrollFrame = scrollFrame - - spellsTab.ApplyStandardBackdrop(container, scrollFrame) - - --~header - local headerOptions = { - padding = 2, - - header_height = 14, - reziser_shown = true, - reziser_width = 2, - reziser_color = {.5, .5, .5, 0.7}, - reziser_max_width = 246, - - header_click_callback = onColumnHeaderClickCallback, - - header_backdrop_color = {0.1, 0.1, 0.1, 0.4}, - text_color = {1, 1, 1, 0.823}, - } - - local headerTable = {} - - ---create the header frame, the header frame is the frame which shows the columns names to describe the data shown in the scrollframe - ---@type df_headerframe - local header = DetailsFramework:CreateHeader(container, headerTable, headerOptions) - scrollFrame.Header = header - scrollFrame.Header:SetPoint("topleft", scrollFrame, "topleft", 0, 1) - scrollFrame.Header:SetColumnSettingChangedCallback(onHeaderColumnOptionChanged) - - --cache the containerType which this header is used for - headerContainerType[scrollFrame.Header] = "spells" - - --create the scroll lines - for i = 1, defaultAmountOfLines do - scrollFrame:CreateLine(spellsTab.CreateSpellBar) - end - - ---set the data and refresh the scrollframe - ---@param self breakdownspellscrollframe - ---@param data breakdownspelldatalist - function scrollFrame:RefreshMe(data) --~refreshme (spells) ~refreshmes - --get which column is currently selected and the sort order - local columnIndex, order, key = scrollFrame.Header:GetSelectedColumn() - scrollFrame.SortKey = key - scrollFrame.SortOrder = order - - ---@type string - local keyToSort = key - - ---@type combat - local combatObject = spellsTab.GetCombat() - ---@type number, number - local mainAttribute, subAttribute = spellsTab.GetInstance():GetDisplay() - - --filling necessary information to sort the data by the selected header column - for i = 1, #data do - ---@type spelltableadv - local bkSpellData = data[i] - if (not bkSpellData[keyToSort]) then - local value = getValueForHeaderSortKey(combatObject, bkSpellData, keyToSort) - bkSpellData[keyToSort] = value - end - end - - if (order == "DESC") then - table.sort(data, - ---@param t1 spelltableadv - ---@param t2 spelltableadv - function(t1, t2) - return t1[keyToSort] > t2[keyToSort] - end) - self.topValue = data[1] and data[1][keyToSort] - else - table.sort(data, - ---@param t1 spelltableadv - ---@param t2 spelltableadv - function(t1, t2) - return t1[keyToSort] < t2[keyToSort] - end) - self.topValue = data[#data] and data[#data][keyToSort] - end - - self:SetData(data) - self:Refresh() - end - - return scrollFrame -end - ----on enter function for the spell target frame ----@param targetFrame breakdowntargetframe -local onEnterSpellTarget = function(targetFrame) - --the spell target frame is created in the statusbar which is placed above the line frame - local lineBar = targetFrame:GetParent():GetParent() - local spellId = targetFrame.spellId - - ---@type actor - local actorObject = Details:GetActorObjectFromBreakdownWindow() - - local targets - if (targetFrame.bIsMainLine) then - ---@type spelltableadv - local bkSpellData = targetFrame.bkSpellData - targets = actorObject:BuildSpellTargetFromBreakdownSpellData(bkSpellData) - else - local spellTable = targetFrame.spellTable - targets = actorObject:BuildSpellTargetFromSpellTable(spellTable) - end - - ---@type number the top value of targets - local topValue = targets[1] and targets[1][2] or 0 - - local cooltip = GameCooltip - cooltip:Preset(2) - - for targetIndex, targetTable in ipairs(targets) do - local targetName = targetTable[1] - local value = targetTable[2] - cooltip:AddLine(targetIndex .. ". " .. targetName, Details:Format(value)) - GameCooltip:AddIcon(CONST_TARGET_TEXTURE, 1, 1, 14, 14) - Details:AddTooltipBackgroundStatusbar(false, value / topValue * 100) - end - - cooltip:SetOwner(targetFrame) - cooltip:Show() -end - -local onLeaveSpellTarget = function(self) - GameTooltip:Hide() - GameCooltip:Hide() - self:GetParent():GetParent():GetScript("OnLeave")(self:GetParent():GetParent()) - self.texture:SetAlpha(.7) - self:SetAlpha(.7) -end ---@param targetBar breakdowntargetbar local onEnterBreakdownTargetBar = function(targetBar) @@ -3068,138 +1747,7 @@ function spellsTab.UpdateBarSettings(bar) end end ----create a spellbar within the spell scroll ----@param self breakdownspellscrollframe ----@param index number ----@return breakdownspellbar -function spellsTab.CreateSpellBar(self, index) --~spellbar ~spellline ~spell ~create ~createline ~createspell ~createspellbar - ---@type breakdownspellbar - local spellBar = CreateFrame("button", self:GetName() .. "SpellBarButton" .. index, self) - spellBar.index = index - --size and positioning - spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT) - local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15 - spellBar:SetPoint("topleft", self, "topleft", 1, y) - spellBar:SetPoint("topright", self, "topright", -1, y) - - spellBar:EnableMouse(true) - spellBar:RegisterForClicks("AnyUp", "AnyDown") - spellBar:SetAlpha(0.823) - spellBar:SetFrameStrata("HIGH") - spellBar:SetScript("OnEnter", onEnterSpellBar) - spellBar:SetScript("OnLeave", onLeaveSpellBar) - spellBar:SetScript("OnMouseDown", onMouseDownBreakdownSpellBar) - spellBar:SetScript("OnMouseUp", onMouseUpBreakdownSpellBar) - spellBar.onMouseUpTime = 0 - spellBar.ExpandedChildren = {} - - DF:Mixin(spellBar, DF.HeaderFunctions) - - ---@type breakdownspellbarstatusbar - local statusBar = CreateFrame("StatusBar", "$parentStatusBar", spellBar) - statusBar:SetAllPoints() - statusBar:SetAlpha(0.5) - statusBar:SetMinMaxValues(0, 100) - statusBar:SetValue(50) - statusBar:EnableMouse(false) - statusBar:SetFrameLevel(spellBar:GetFrameLevel() - 1) - spellBar.statusBar = statusBar - - ---@type texture this is the statusbar texture - local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork") - statusBar:SetStatusBarTexture(statusBarTexture) - statusBar:SetStatusBarColor(1, 1, 1, 1) - - ---@type texture background texture - local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border") - backgroundTexture:SetAllPoints() - statusBar.backgroundTexture = backgroundTexture - - ---@type texture overlay texture to use when the spellbar is selected - local statusBarOverlayTexture = statusBar:CreateTexture("$parentTextureOverlay", "overlay", nil, 7) - statusBarOverlayTexture:SetTexture([[Interface/AddOns/Details/images/overlay_indicator_1]]) - statusBarOverlayTexture:SetVertexColor(1, 1, 1, 0.2) - statusBarOverlayTexture:SetAllPoints() - statusBarOverlayTexture:Hide() - spellBar.overlayTexture = statusBarOverlayTexture - statusBar.overlayTexture = statusBarOverlayTexture - - ---@type texture shown when the mouse hoverover this spellbar - local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight") - hightlightTexture:SetColorTexture(1, 1, 1, 0.2) - hightlightTexture:SetAllPoints() - statusBar.highlightTexture = hightlightTexture - - --button to expand the bar when there's spells merged - ---@type breakdownexpandbutton - local expandButton = CreateFrame("button", "$parentExpandButton", spellBar, "BackdropTemplate") - expandButton:SetSize(CONST_BAR_HEIGHT, CONST_BAR_HEIGHT) - expandButton:RegisterForClicks("LeftButtonDown") - spellBar.expandButton = expandButton - - ---@type texture - local expandButtonTexture = expandButton:CreateTexture("$parentTexture", "artwork") - expandButtonTexture:SetPoint("center", expandButton, "center", 0, 0) - expandButtonTexture:SetSize(CONST_BAR_HEIGHT-2, CONST_BAR_HEIGHT-2) - expandButton.texture = expandButtonTexture - - --frame which will show the spell tooltip - ---@type frame - local spellIconFrame = CreateFrame("frame", "$parentIconFrame", spellBar, "BackdropTemplate") - spellIconFrame:SetSize(CONST_BAR_HEIGHT - 2, CONST_BAR_HEIGHT - 2) - spellIconFrame:SetScript("OnEnter", onEnterSpellIconFrame) - spellIconFrame:SetScript("OnLeave", onLeaveSpellIconFrame) - spellBar.spellIconFrame = spellIconFrame - - --create the icon to show the spell texture - ---@type texture - local spellIcon = spellIconFrame:CreateTexture("$parentTexture", "overlay") - spellIcon:SetAllPoints() - spellIcon:SetTexCoord(.1, .9, .1, .9) - spellBar.spellIcon = spellIcon - - --create a square frame which is placed at the right side of the line to show which targets for damaged by the spell - ---@type breakdowntargetframe - local targetsSquareFrame = CreateFrame("frame", "$parentTargetsFrame", statusBar, "BackdropTemplate") - targetsSquareFrame:SetSize(CONST_SPELLSCROLL_LINEHEIGHT, CONST_SPELLSCROLL_LINEHEIGHT) - targetsSquareFrame:SetAlpha(.7) - targetsSquareFrame:SetScript("OnEnter", onEnterSpellTarget) - targetsSquareFrame:SetScript("OnLeave", onLeaveSpellTarget) - targetsSquareFrame:SetFrameLevel(statusBar:GetFrameLevel()+2) - spellBar.targetsSquareFrame = targetsSquareFrame - - ---@type texture - local targetTexture = targetsSquareFrame:CreateTexture("$parentTexture", "overlay") - targetTexture:SetTexture(CONST_TARGET_TEXTURE) - targetTexture:SetAllPoints() - targetTexture:SetDesaturated(true) - spellBar.targetsSquareTexture = targetTexture - targetsSquareFrame.texture = targetTexture - - spellBar:AddFrameToHeaderAlignment(spellIconFrame) - spellBar:AddFrameToHeaderAlignment(targetsSquareFrame) - - --create texts - ---@type fontstring[] - spellBar.InLineTexts = {} - - for i = 1, 16 do - ---@type fontstring - local fontString = spellBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall") - fontString:SetJustifyH("left") - fontString:SetTextColor(1, 1, 1, 1) - fontString:SetNonSpaceWrap(true) - fontString:SetWordWrap(false) - spellBar["lineText" .. i] = fontString - spellBar.InLineTexts[i] = fontString - fontString:SetTextColor(1, 1, 1, 1) - spellBar:AddFrameToHeaderAlignment(fontString) - end - - spellBar:AlignWithHeader(self.Header, "left") - return spellBar -end ----------------------------------------------------------------------------------------------------------------------- --> create the new tab diff --git a/frames/window_playerbreakdown_spells_options.lua b/frames/window_breakdown/window_playerbreakdown_spells_options.lua similarity index 100% rename from frames/window_playerbreakdown_spells_options.lua rename to frames/window_breakdown/window_playerbreakdown_spells_options.lua diff --git a/frames/window_main.lua b/frames/window_main.lua index af0879c2..97d659ce 100644 --- a/frames/window_main.lua +++ b/frames/window_main.lua @@ -1989,11 +1989,12 @@ local lineScript_Onmouseup = function(self, button) end end - if (Details.row_singleclick_overwrite [instanceObject.atributo] and type(Details.row_singleclick_overwrite [instanceObject.atributo][instanceObject.sub_atributo]) == "function") then - return Details.row_singleclick_overwrite [instanceObject.atributo][instanceObject.sub_atributo] (_, self.minha_tabela, instanceObject, bIsShiftDown, bIsControlDown) + --if there's a function to overwrite the default behavior + if (Details.row_singleclick_overwrite[instanceObject.atributo] and type(Details.row_singleclick_overwrite[instanceObject.atributo][instanceObject.sub_atributo]) == "function") then + return Details.row_singleclick_overwrite[instanceObject.atributo][instanceObject.sub_atributo](_, self.minha_tabela, instanceObject, bIsShiftDown, bIsControlDown) end - return Details:ReportSingleLine (instanceObject, self) + return Details:ReportSingleLine(instanceObject, self) end if (not self.minha_tabela) then