772 lines
29 KiB
Lua
772 lines
29 KiB
Lua
|
|
--this file controls the left panel of the breakdown window, where the player list and plugins are shown
|
|
---@type details
|
|
local Details = _G.Details
|
|
|
|
---@class detailsframework
|
|
local detailsFramework = _G.DetailsFramework
|
|
|
|
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
|
|
local addonName, Details222 = ...
|
|
|
|
local breakdownWindowPlayerList = {}
|
|
|
|
local unpack = table.unpack or unpack
|
|
local C_Timer = _G.C_Timer
|
|
local tinsert = table.insert
|
|
local CreateFrame = CreateFrame
|
|
local GetSpecializationInfoByID = GetSpecializationInfoByID
|
|
local PixelUtil = PixelUtil
|
|
|
|
local scrollbox_size = {215, 405}
|
|
local scrollbox_lines = 20
|
|
local player_line_height = 20
|
|
local scrollbox_line_backdrop_color = {0.2, 0.2, 0.2, 0.5}
|
|
local scrollbox_line_backdrop_color_selected = {1, 1, 0, 0.45}
|
|
local scrollbox_line_backdrop_color_highlight = {.9, .9, .9, 0.5}
|
|
local player_scroll_size = {195, 288}
|
|
|
|
---@type table<uniquecombatid, actorname>
|
|
local lastSelectedPlayerPerSegment = {}
|
|
|
|
---@type actorname
|
|
local lastSelectedPlayerName = ""
|
|
|
|
local onPlayerSelected = function(breakdownWindowFrame, playerObject)
|
|
---@type instance
|
|
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
|
Details:OpenBreakdownWindow(instanceObject, playerObject, false, true)
|
|
|
|
--cache the latest selected player for this combat
|
|
---@type combat
|
|
local combatObject = instanceObject:GetCombat()
|
|
---@type actorname
|
|
local playerName = playerObject:Name()
|
|
|
|
lastSelectedPlayerPerSegment[combatObject:GetCombatUID()] = playerName
|
|
lastSelectedPlayerName = playerName
|
|
|
|
breakdownWindowFrame.playerScrollBox:Refresh()
|
|
end
|
|
|
|
local getActorToShowInBreakdownWindow = function(combatObject)
|
|
---@type breakdownwindow
|
|
local breakdownWindowFrame = Details.BreakdownWindowFrame
|
|
|
|
--when the select is selected, figure out which player need to be selected in the playerScroll
|
|
---@type instance
|
|
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
|
---@type uniquecombatid
|
|
local combatUID = combatObject:GetCombatUID()
|
|
|
|
local displayId, subDisplayId = instanceObject:GetDisplay()
|
|
|
|
---@type actorname
|
|
local playerName = lastSelectedPlayerPerSegment[combatUID]
|
|
|
|
if (playerName) then
|
|
---@type actor
|
|
local playerObject = combatObject:GetActor(displayId, playerName)
|
|
return playerObject
|
|
else
|
|
---@type actor
|
|
local playerObject = combatObject:GetActor(displayId, lastSelectedPlayerName)
|
|
if (playerObject) then
|
|
lastSelectedPlayerPerSegment[combatUID] = playerObject:Name()
|
|
return playerObject
|
|
else
|
|
playerObject = combatObject:GetActor(displayId, Details.playername)
|
|
if (playerObject) then
|
|
lastSelectedPlayerPerSegment[combatUID] = playerObject:Name()
|
|
return playerObject
|
|
end
|
|
|
|
--get the top player from the combat display and subDisplay and select it
|
|
---@type actor
|
|
local actorObject = instanceObject:GetActorBySubDisplayAndRank(displayId, subDisplayId, 1)
|
|
if (actorObject) then
|
|
lastSelectedPlayerPerSegment[combatUID] = actorObject:Name()
|
|
return actorObject
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---this function get the list of active plugins which has a frame to show in the breakdown window and create a button for each one
|
|
---@param breakdownWindowFrame breakdownwindow
|
|
---@param pluginsFrame frame
|
|
---@param breakdownSideMenu frame
|
|
---@return number height how much space pluginsFrame is using
|
|
local refreshPluginButtons = function(breakdownWindowFrame, pluginsFrame, breakdownSideMenu)
|
|
local amountPluginButtons = #breakdownWindowFrame.RegisteredPluginButtons
|
|
local pluginButtonHeight = 20
|
|
local spacingBetweenButtons = 1
|
|
local totalHeight = 0
|
|
|
|
for i = 1, amountPluginButtons do
|
|
---@type button
|
|
local pluginButton = breakdownWindowFrame.RegisteredPluginButtons[i]
|
|
pluginButton:Show()
|
|
PixelUtil.SetSize(pluginButton, pluginsFrame:GetWidth() - 4, pluginButtonHeight)
|
|
pluginButton:ClearAllPoints()
|
|
|
|
if (i == 1) then
|
|
PixelUtil.SetPoint(pluginButton, "topleft", pluginsFrame, "topleft", 2, -22)
|
|
else
|
|
PixelUtil.SetPoint(pluginButton, "topleft", breakdownWindowFrame.RegisteredPluginButtons[i - 1], "bottomleft", 0, -spacingBetweenButtons)
|
|
end
|
|
|
|
local fontString = _G[pluginButton:GetName() .. "_Text"]
|
|
Details222.BreakdownWindow.ApplyFontSettings(fontString)
|
|
|
|
totalHeight = totalHeight + pluginButtonHeight + spacingBetweenButtons
|
|
end
|
|
|
|
--add the height of the header and the spacing between the header and the first button and the last button and the bottom of the frame
|
|
totalHeight = totalHeight + 20 + 2
|
|
|
|
pluginsFrame:SetPoint("topleft", breakdownSideMenu, "topleft", 0, 0)
|
|
pluginsFrame:SetWidth(breakdownSideMenu:GetWidth())
|
|
pluginsFrame:SetHeight(amountPluginButtons * pluginButtonHeight + 22 + (amountPluginButtons * 1))
|
|
|
|
return totalHeight
|
|
end
|
|
|
|
local createPlayerScrollBox = function(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
|
local refreshPlayerScrollFunc = function(self, data, offset, totalLines)
|
|
local topResult = data[1]
|
|
if (topResult) then
|
|
topResult = topResult.total
|
|
end
|
|
|
|
---@type combat
|
|
local combatObject = Details:GetCombatFromBreakdownWindow()
|
|
local encounterId = combatObject:GetEncounterCleuID()
|
|
local difficultyId = combatObject:GetDifficulty()
|
|
|
|
for i = 1, totalLines do --~refresh
|
|
local index = i + offset
|
|
local playerObject = data[index]
|
|
if (playerObject) then
|
|
local line = self:GetLine(i)
|
|
if (line) then
|
|
line.playerObject = playerObject
|
|
line.combatObject = combatObject
|
|
line.index = index
|
|
line:UpdateLine(topResult, encounterId, difficultyId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local lineOnClick = function(self)
|
|
if (self.playerObject ~= Details:GetActorObjectFromBreakdownWindow() or breakdownWindowFrame.shownPluginObject) then
|
|
onPlayerSelected(breakdownWindowFrame, self.playerObject)
|
|
end
|
|
end
|
|
|
|
local lineOnEnter = function(self)
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_highlight))
|
|
self.specIcon:SetBlendMode("ADD")
|
|
self.roleIcon:SetBlendMode("ADD")
|
|
end
|
|
|
|
local lineOnLeave = function(self)
|
|
if (self.isSelected) then
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
|
else
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
|
end
|
|
self.specIcon:SetBlendMode("BLEND")
|
|
self.roleIcon:SetBlendMode("BLEND")
|
|
end
|
|
|
|
local updatePlayerLine = function(self, topResult, encounterId, difficultyId) --~update
|
|
local playerSelected = lastSelectedPlayerName
|
|
if (playerSelected == self.playerObject:Name()) then
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
|
self.isSelected = true
|
|
else
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
|
self.isSelected = nil
|
|
end
|
|
|
|
local specRole
|
|
|
|
--adjust the player icon
|
|
if (self.playerObject.spellicon) then
|
|
self.specIcon:SetTexture(self.playerObject.spellicon)
|
|
self.specIcon:SetTexCoord(.1, .9, .1, .9)
|
|
else
|
|
local specIcon, L, R, T, B = Details:GetSpecIcon(self.playerObject.spec, false)
|
|
|
|
if (specIcon) then
|
|
self.specIcon:SetTexture(specIcon)
|
|
self.specIcon:SetTexCoord(L, R, T, B)
|
|
|
|
specRole = "NONE"
|
|
else
|
|
self.specIcon:SetTexture("")
|
|
end
|
|
end
|
|
|
|
--adjust the role icon
|
|
if (specRole) then
|
|
local roleIcon, L, R, T, B = Details:GetRoleIcon(specRole)
|
|
if (roleIcon) then
|
|
self.roleIcon:SetTexture(roleIcon)
|
|
self.roleIcon:SetTexCoord(L, R, T, B)
|
|
else
|
|
self.roleIcon:SetTexture("")
|
|
end
|
|
else
|
|
self.roleIcon:SetTexture("")
|
|
end
|
|
|
|
local playerGear = openRaidLib and openRaidLib.GetUnitGear(self.playerObject.nome)
|
|
|
|
--do not show the role icon
|
|
self.roleIcon:SetTexture("") --not in use
|
|
|
|
--set the player name
|
|
self.playerName:SetText(Details:GetOnlyName(self.playerObject.nome))
|
|
self.rankText:SetText(self.index) --not in use
|
|
|
|
--item level
|
|
local itemLevel = Details.ilevel:GetIlvl(self.playerObject.serial)
|
|
self.itemLevelText:SetText((itemLevel and itemLevel.ilvl and math.floor(itemLevel.ilvl)) or (self.playerObject.ilvl) or (playerGear and playerGear.ilevel) or "0")
|
|
|
|
local actorSpecId = self.playerObject.spec
|
|
local actorTotal = self.playerObject.total
|
|
local combatObject = self.combatObject
|
|
|
|
-- we dont have warcraft logs or any percentile stuff.
|
|
self.percentileText:SetText("N/A")
|
|
self.percentileText:SetAlpha(0.25)
|
|
|
|
Details222.BreakdownWindow.ApplyFontSettings(self.playerName)
|
|
Details222.BreakdownWindow.ApplyFontSettings(self.itemLevelText)
|
|
Details222.BreakdownWindow.ApplyFontSettings(self.percentileText)
|
|
|
|
Details222.BreakdownWindow.ApplyTextureSettings(self.totalStatusBar)
|
|
|
|
--set the statusbar
|
|
local r, g, b = self.playerObject:GetClassColor()
|
|
self.totalStatusBar:SetStatusBarColor(r, g, b, 1)
|
|
self.totalStatusBar:SetMinMaxValues(0, topResult)
|
|
self.totalStatusBar:SetValue(actorTotal)
|
|
end
|
|
|
|
--get a Details! window
|
|
local lowerInstanceId = Details:GetLowerInstanceNumber()
|
|
local fontFile
|
|
local fontSize
|
|
local fontOutline
|
|
|
|
--header setup
|
|
local headerTable = {
|
|
{text = "", width = 20},
|
|
{text = "Player Name", width = 100},
|
|
{text = "iLvL", width = 30},
|
|
{text = "WCL Parse", width = 60},
|
|
}
|
|
local headerOptions = {
|
|
padding = 2,
|
|
}
|
|
|
|
if (lowerInstanceId) then
|
|
local instance = Details:GetInstance(lowerInstanceId)
|
|
if (instance) then
|
|
fontFile = instance.row_info.font_face
|
|
fontSize = instance.row_info.font_size
|
|
fontOutline = instance.row_info.textL_outline
|
|
end
|
|
end
|
|
|
|
local createPlayerLine = function(self, index)
|
|
--create a new line
|
|
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
|
detailsFramework:SetTemplate(line, "STANDARD_GRAY")
|
|
|
|
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
|
|
|
---@type frame
|
|
local OTTFrame = CreateFrame("frame", nil, line)
|
|
OTTFrame:SetFrameLevel(line:GetFrameLevel()+2)
|
|
OTTFrame:SetAllPoints()
|
|
line.OTTFrame = OTTFrame
|
|
|
|
PixelUtil.SetPoint(line, "topleft", breakdownWindowFrame.PlayerSelectionHeader, "topleft", 1, -((index) * (player_line_height+1)))
|
|
PixelUtil.SetSize(line, scrollbox_size[1]-2, player_line_height)
|
|
|
|
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
|
|
line:SetScript("OnEnter", lineOnEnter)
|
|
line:SetScript("OnLeave", lineOnLeave)
|
|
line:SetScript("OnClick", lineOnClick)
|
|
|
|
local specIcon = OTTFrame:CreateTexture("$parentSpecIcon", "artwork")
|
|
specIcon:SetSize(headerTable[1].width - 1, headerTable[1].width - 1)
|
|
specIcon:SetAlpha(0.834)
|
|
|
|
local roleIcon = OTTFrame:CreateTexture("$parentRoleIcon", "overlay")
|
|
roleIcon:SetSize((player_line_height-2) / 2, (player_line_height-2) / 2)
|
|
roleIcon:SetAlpha(0.71)
|
|
|
|
local playerName = OTTFrame:CreateFontString("$parentPlayerName", "artwork", "GameFontNormal")
|
|
playerName:SetTextColor(1, 1, 1, .9)
|
|
|
|
local className = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
|
className.textcolor = {.95, .8, .2, 0}
|
|
className.textsize = 9
|
|
|
|
local itemLevelText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
|
itemLevelText.textcolor = {1, 1, 1, .7}
|
|
itemLevelText.textsize = 11
|
|
|
|
local percentileText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
|
percentileText.textcolor = {1, 1, 1, .7}
|
|
percentileText.textsize = 11
|
|
|
|
local rankText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
|
rankText.textcolor = {.3, .3, .3, .7}
|
|
rankText.textsize = fontSize
|
|
|
|
local totalStatusBar = CreateFrame("statusbar", nil, line)
|
|
totalStatusBar:SetSize(scrollbox_size[1]-player_line_height, player_line_height)
|
|
totalStatusBar:SetMinMaxValues(0, 100)
|
|
totalStatusBar:SetFrameLevel(line:GetFrameLevel()+1)
|
|
totalStatusBar:SetAlpha(0.5)
|
|
totalStatusBar:SetPoint("bottomleft", specIcon, "bottomright", 0, 0)
|
|
|
|
local gradientTexture = DetailsFramework:CreateTexture(OTTFrame, {gradient = "horizontal", fromColor = {.1, .1, .1, .634}, toColor = "transparent"}, 100, 1, "border", {0, 1, 0, 1}, "segmentsGradient")
|
|
gradientTexture:SetPoint("lefts")
|
|
|
|
line.specIcon = specIcon
|
|
line.roleIcon = roleIcon
|
|
line.playerName = playerName
|
|
line.className = className
|
|
line.rankText = rankText
|
|
line.totalStatusBar = totalStatusBar
|
|
line.itemLevelText = itemLevelText
|
|
line.percentileText = percentileText
|
|
|
|
line:AddFrameToHeaderAlignment(specIcon)
|
|
line:AddFrameToHeaderAlignment(playerName)
|
|
line:AddFrameToHeaderAlignment(itemLevelText)
|
|
line:AddFrameToHeaderAlignment(percentileText)
|
|
|
|
line:AlignWithHeader(breakdownWindowFrame.PlayerSelectionHeader, "left")
|
|
|
|
line.UpdateLine = updatePlayerLine
|
|
|
|
return line
|
|
end
|
|
|
|
---@type width
|
|
local width = player_scroll_size[1] + 22
|
|
---@type height
|
|
local height = player_scroll_size[2]
|
|
|
|
local playerScroll = detailsFramework:CreateScrollBox(breakdownSideMenu, "DetailsBreakdownWindowPlayerScrollBox", refreshPlayerScrollFunc, {}, width, height, scrollbox_lines, player_line_height)
|
|
detailsFramework:ReskinSlider(playerScroll)
|
|
playerScroll.ScrollBar:ClearAllPoints()
|
|
playerScroll.ScrollBar:SetPoint("topright", playerScroll, "topright", -2, -37)
|
|
playerScroll.ScrollBar:SetPoint("bottomright", playerScroll, "bottomright", -2, 17)
|
|
breakdownWindowFrame.playerScrollBox = playerScroll
|
|
playerScroll.ScrollBar:Hide()
|
|
|
|
--remove the standard backdrop
|
|
playerScroll:SetBackdrop({})
|
|
playerScroll:SetBackdropColor(0, 0, 0, 0)
|
|
playerScroll:SetBackdropBorderColor(0, 0, 0, 0)
|
|
playerScroll.__background:Hide()
|
|
|
|
--create the header frame for the player scrollbox selection
|
|
---@type df_headerframe
|
|
breakdownWindowFrame.PlayerSelectionHeader = DetailsFramework:CreateHeader(playerScroll, headerTable, headerOptions)
|
|
breakdownWindowFrame.PlayerSelectionHeader:SetAlpha(0.823)
|
|
breakdownWindowFrame.PlayerSelectionHeader:SetPoint("topleft", playerSelectionHeaderFrame, "bottomleft", 0, -2)
|
|
breakdownWindowFrame.PlayerSelectionHeader:SetPoint("topright", playerSelectionHeaderFrame, "bottomright", 0, -2)
|
|
|
|
detailsFramework:ApplyStandardBackdrop(breakdownWindowFrame.PlayerSelectionHeader)
|
|
breakdownWindowFrame.PlayerSelectionHeader.__background:SetTexture(.60, .60, .60)
|
|
|
|
--create the scrollbox lines
|
|
for i = 1, scrollbox_lines do
|
|
playerScroll:CreateLine(createPlayerLine)
|
|
end
|
|
|
|
return playerScroll
|
|
end
|
|
|
|
local createSegmentsScrollBox = function(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
|
local refreshSegmentsScrollFunc = function(self, data, offset, totalLines)
|
|
for lineIndex = 1, totalLines do --~refresh
|
|
local index = lineIndex + offset
|
|
---@type breakdownsegmentdata
|
|
local segmentData = data[index]
|
|
if (segmentData) then
|
|
---@type breakdownsegmentline
|
|
local line = self:GetLine(lineIndex)
|
|
if (line) then
|
|
line:UpdateLine(lineIndex, segmentData)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local lineOnClick = function(self)
|
|
--unique combat id from the button clicked
|
|
local combatUniqueID = self.combatUniqueID
|
|
if (not Details:DoesCombatWithUIDExists(combatUniqueID)) then
|
|
Details:Msg("This segment is not available anymore.")
|
|
return
|
|
end
|
|
|
|
--current breakdown combat
|
|
local currentBKCombat = Details:GetCombatFromBreakdownWindow()
|
|
--unique combat id from the combat the breakdown window is using
|
|
local currentBKCombatUniqueID = currentBKCombat:GetCombatUID()
|
|
|
|
if (combatUniqueID ~= currentBKCombatUniqueID) then
|
|
local newCombatToShowInBreakdownWindow = Details:GetCombatByUID(combatUniqueID)
|
|
if (newCombatToShowInBreakdownWindow) then
|
|
---@cast newCombatToShowInBreakdownWindow combat
|
|
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
|
--set the segment of the instance to be the segment just selected by the user
|
|
instanceObject:SetSegment(newCombatToShowInBreakdownWindow:GetSegmentSlotId())
|
|
|
|
local bFromAttributeChange = false
|
|
local bIsRefresh = true
|
|
|
|
local actor = getActorToShowInBreakdownWindow(newCombatToShowInBreakdownWindow)
|
|
if (actor) then
|
|
Details:OpenBreakdownWindow(instanceObject, actor, bFromAttributeChange, bIsRefresh)
|
|
else
|
|
local actorObject = Details:GetActorObjectFromBreakdownWindow()
|
|
lastSelectedPlayerPerSegment[combatUniqueID] = actorObject:Name()
|
|
Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttributeChange, bIsRefresh)
|
|
end
|
|
|
|
breakdownWindowFrame.segmentScrollBox:Refresh()
|
|
end
|
|
end
|
|
end
|
|
|
|
local lineOnEnter = function(self)
|
|
if (not self.isSelected) then
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_highlight))
|
|
end
|
|
end
|
|
|
|
local lineOnLeave = function(self)
|
|
if (not self.isSelected) then
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
|
end
|
|
end
|
|
|
|
---update the segment line from the segments scrollbox
|
|
---@param self breakdownsegmentline
|
|
---@param index number
|
|
---@param segmentData breakdownsegmentdata
|
|
local updateSegmentLine = function(self, index, segmentData) --~update
|
|
local combatName = segmentData.combatName
|
|
local r, g, b = segmentData.r, segmentData.g, segmentData.b
|
|
local combatIcon1 = segmentData.combatIcon
|
|
|
|
self.segmentText:SetText(combatName)
|
|
Details222.BreakdownWindow.ApplyFontSettings(self.segmentText)
|
|
|
|
self.segmentText:SetTextColor(r, g, b)
|
|
detailsFramework:TruncateText(self.segmentText, player_scroll_size[1] - 20)
|
|
|
|
local bUseAtlasSize = true
|
|
detailsFramework:SetAtlas(self.segmentIcon, combatIcon1, bUseAtlasSize)
|
|
|
|
self.combatUniqueID = segmentData.UID
|
|
|
|
local combatSelected = Details:GetCombatFromBreakdownWindow()
|
|
if (combatSelected and combatSelected:GetCombatUID() == segmentData.UID) then
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
|
self.isSelected = true
|
|
else
|
|
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
|
self.isSelected = false
|
|
end
|
|
end
|
|
|
|
--header setup
|
|
local headerTable = {
|
|
{text = "Segment Name", width = 100},
|
|
}
|
|
local headerOptions = {
|
|
padding = 2,
|
|
}
|
|
|
|
local createSegmentLine = function(self, index)
|
|
--create a new line
|
|
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
|
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
|
detailsFramework:SetTemplate(line, "STANDARD_GRAY")
|
|
|
|
PixelUtil.SetPoint(line, "topleft", self, "topleft", 1, -((index-1) * (player_line_height+1)))
|
|
PixelUtil.SetSize(line, scrollbox_size[1]-2, player_line_height)
|
|
|
|
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
|
|
line:SetScript("OnEnter", lineOnEnter)
|
|
line:SetScript("OnLeave", lineOnLeave)
|
|
line:SetScript("OnClick", lineOnClick)
|
|
|
|
--segment icon, this icon will tell which type of segment the line is
|
|
---@type df_image
|
|
local segmentIcon = detailsFramework:CreateTexture(line, "", player_line_height, player_line_height - 1, "artwork")
|
|
segmentIcon:SetSize(player_line_height - 4, player_line_height - 4)
|
|
segmentIcon:SetAlpha(0.834)
|
|
|
|
local segmentText = line:CreateFontString("$parentSegmentName", "artwork", "GameFontNormal")
|
|
line.segmentText = segmentText
|
|
line.segmentIcon = segmentIcon
|
|
|
|
--create a texture gradient in horizontal with the left side starting from black and the right side ending in transparent, the width is 40 and is placed at the left side of the line
|
|
local gradientTexture = DetailsFramework:CreateTexture(line, {gradient = "horizontal", fromColor = {.1, .1, .1, .634}, toColor = "transparent"}, 100, 1, "border", {0, 1, 0, 1}, "segmentsGradient")
|
|
gradientTexture:SetPoint("lefts")
|
|
|
|
segmentIcon:SetPoint("left", line, "left", 2, 0)
|
|
segmentText:SetPoint("left", segmentIcon.widget, "right", 5, 0)
|
|
|
|
line.UpdateLine = updateSegmentLine
|
|
|
|
return line
|
|
end
|
|
|
|
---@type width
|
|
local width = player_scroll_size[1] + 22
|
|
---@type height
|
|
local height = player_scroll_size[2]
|
|
|
|
local segmentsScroll = detailsFramework:CreateScrollBox(breakdownSideMenu, "DetailsBreakdownWindowSegmentsScrollBox", refreshSegmentsScrollFunc, {}, width, height, scrollbox_lines, player_line_height)
|
|
detailsFramework:ReskinSlider(segmentsScroll)
|
|
|
|
segmentsScroll.ScrollBar:ClearAllPoints()
|
|
segmentsScroll.ScrollBar:SetPoint("topright", segmentsScroll, "topright", -2, -37)
|
|
segmentsScroll.ScrollBar:SetPoint("bottomright", segmentsScroll, "bottomright", -2, 17)
|
|
segmentsScroll.ScrollBar:Hide()
|
|
|
|
breakdownWindowFrame.segmentScrollBox = segmentsScroll
|
|
|
|
--remove the standard backdrop
|
|
segmentsScroll:SetBackdrop(nil)
|
|
segmentsScroll.__background:Hide()
|
|
|
|
--create the scrollbox lines
|
|
for i = 1, scrollbox_lines do
|
|
segmentsScroll:CreateLine(createSegmentLine)
|
|
end
|
|
|
|
return segmentsScroll
|
|
end
|
|
|
|
function breakdownWindowPlayerList.CreatePlayerListFrame()
|
|
---@type breakdownwindow
|
|
local breakdownWindowFrame = Details.BreakdownWindowFrame
|
|
---@type frame
|
|
local breakdownSideMenu = breakdownWindowFrame.BreakdownSideMenuFrame
|
|
---@type frame
|
|
local pluginsFrame = breakdownWindowFrame.BreakdownPluginSelectionFrame
|
|
|
|
breakdownSideMenu:SetSize(scrollbox_size[1], scrollbox_size[2])
|
|
PixelUtil.SetPoint(breakdownSideMenu, "topright", breakdownWindowFrame, "topleft", -2, 0)
|
|
PixelUtil.SetPoint(breakdownSideMenu, "bottomright", breakdownWindowFrame, "bottomleft", -2, 0)
|
|
|
|
--> create headers
|
|
local sectionHeaderHeight = 20
|
|
--plugins header frame
|
|
local pluginHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
|
PixelUtil.SetPoint(pluginHeaderFrame, "topleft", breakdownSideMenu, "topleft", 2, -0)
|
|
PixelUtil.SetPoint(pluginHeaderFrame, "topright", breakdownSideMenu, "topright", -2, -0)
|
|
pluginHeaderFrame:SetHeight(sectionHeaderHeight)
|
|
--plugins header label
|
|
local titleBarPlugins_TitleLabel = detailsFramework:CreateLabel(pluginHeaderFrame, "Plugins", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "pluginsLabel", nil, "overlay")
|
|
PixelUtil.SetPoint(titleBarPlugins_TitleLabel, "center", pluginHeaderFrame , "center", 0, 0)
|
|
PixelUtil.SetPoint(titleBarPlugins_TitleLabel, "top", pluginHeaderFrame , "top", 0, -5)
|
|
|
|
--player selection header frame
|
|
local playerSelectionHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
|
playerSelectionHeaderFrame:SetHeight(sectionHeaderHeight)
|
|
playerSelectionHeaderFrame:SetPoint("topleft", pluginsFrame, "bottomleft", 0, -1)
|
|
playerSelectionHeaderFrame:SetPoint("topright", pluginsFrame, "bottomright", 0, -1)
|
|
--player selection header label
|
|
--converting from detailsFramework:NewLabel to detailsFramework:CreateLabel
|
|
--local titleBarTools_TitleLabel = detailsFramework:NewLabel(titleBarPlayerSeparator, titleBarPlayerSeparator, nil, "titulo", "Players", "GameFontHighlightLeft", 12, {227/255, 186/255, 4/255})
|
|
local titleBarTools_TitleLabel = detailsFramework:CreateLabel(playerSelectionHeaderFrame, "Select Player", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "playersLabel", nil, "overlay")
|
|
PixelUtil.SetPoint(titleBarTools_TitleLabel, "center", playerSelectionHeaderFrame , "center", 0, 0)
|
|
PixelUtil.SetPoint(titleBarTools_TitleLabel, "top", playerSelectionHeaderFrame , "top", 0, -5)
|
|
|
|
--segment selection header frame
|
|
local segmentSelectionHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
|
segmentSelectionHeaderFrame:SetHeight(sectionHeaderHeight)
|
|
--segment selection header label
|
|
local titleBarSegment_TitleLabel = detailsFramework:CreateLabel(segmentSelectionHeaderFrame, "Select Segment", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "segmentsLabel", nil, "overlay")
|
|
PixelUtil.SetPoint(titleBarSegment_TitleLabel, "center", segmentSelectionHeaderFrame , "center", 0, 0)
|
|
PixelUtil.SetPoint(titleBarSegment_TitleLabel, "top", segmentSelectionHeaderFrame , "top", 0, -5)
|
|
|
|
local playerScroll = createPlayerScrollBox(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
|
playerScroll:SetPoint("topleft", breakdownWindowFrame.PlayerSelectionHeader, "bottomleft", 0, -2)
|
|
playerScroll:SetPoint("topright", breakdownWindowFrame.PlayerSelectionHeader, "bottomright", 0, -2)
|
|
|
|
local segmentsScroll = createSegmentsScrollBox(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
|
segmentsScroll:SetPoint("topleft", playerScroll, "bottomleft", 0, -20)
|
|
segmentsScroll:SetPoint("topright", playerScroll, "bottomright", 0, -20)
|
|
|
|
PixelUtil.SetPoint(segmentSelectionHeaderFrame, "topleft", playerScroll, "bottomleft", 0, -1)
|
|
PixelUtil.SetPoint(segmentSelectionHeaderFrame, "topright", playerScroll, "bottomright", 0, -1)
|
|
|
|
local classIds = detailsFramework.ClassFileNameToIndex
|
|
|
|
---get the player list from the segment and build a table compatible with the scroll box
|
|
---@return actor[]
|
|
function breakdownWindowPlayerList.BuildPlayerList()
|
|
---@type combat
|
|
local combatObject = Details:GetCombatFromBreakdownWindow()
|
|
---@type {key1: actor, key2: number, key3: number}[]
|
|
local playerTable = {}
|
|
|
|
if (combatObject) then
|
|
local displayType = Details:GetDisplayTypeFromBreakdownWindow()
|
|
local containerType = displayType == 1 and DETAILS_ATTRIBUTE_DAMAGE or DETAILS_ATTRIBUTE_HEAL
|
|
---@type actorcontainer
|
|
local actorContainer = combatObject:GetContainer(containerType)
|
|
|
|
for index, actorObject in actorContainer:ListActors() do
|
|
---@cast actorObject actor
|
|
if (actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then
|
|
local unitClassID = classIds[actorObject:Class()] or 13
|
|
local unitName = actorObject:Name()
|
|
--actor position calculation: if two actors has the same amount of a total number, the sort function would flip they around, so we need to add a unique number to the position based on the class and the two first letters of the name
|
|
local playerPosition = (((unitClassID or 0) + 128) ^ 4) + tonumber(string.byte(unitName, 1) .. "" .. string.byte(unitName, 2))
|
|
|
|
---@type {key1: actor, key2: number, key3: number}
|
|
local data = {actorObject, playerPosition, actorObject.total}
|
|
tinsert(playerTable, data)
|
|
end
|
|
end
|
|
end
|
|
|
|
table.sort(playerTable, detailsFramework.SortOrder3)
|
|
|
|
---@type actor[]
|
|
local resultTable = {}
|
|
for i = 1, #playerTable do
|
|
---@type actor
|
|
local actor = playerTable[i][1]
|
|
resultTable[#resultTable+1] = actor
|
|
end
|
|
|
|
return resultTable
|
|
end
|
|
|
|
local updatePlayerAndSegmentsList = function()
|
|
--the left menu side has 620 pixels of height
|
|
|
|
--when updating the player list, update the plugin buttons as well for convenience
|
|
--the refreshPluginButtons function returns the height occupied by the pluginsFrame
|
|
--this height is then used to set the amount of lines the player and segments scroll frames will show
|
|
local heightOccupied = refreshPluginButtons(breakdownWindowFrame, pluginsFrame, breakdownSideMenu)
|
|
|
|
--the height of the player and segments scroll is determined by the height of the pluginsFrame, by the amount of players needed to be shown and the amount of segments needed to be shown
|
|
--calculate the height "free" to use for both scrolls
|
|
local heightFree = breakdownSideMenu:GetHeight() - heightOccupied
|
|
--the -60 is the space used by the player and segments labels, plus the player scroll header
|
|
--the -5 is the space between the player and segments scroll
|
|
heightFree = heightFree - 60 - 5
|
|
|
|
---@type actor[]
|
|
local playerList = breakdownWindowPlayerList.BuildPlayerList()
|
|
|
|
local amountOfLines = math.floor(heightFree / player_line_height)
|
|
|
|
local linesForPlayerScroll = math.floor(amountOfLines/2)
|
|
if (linesForPlayerScroll < 5) then
|
|
linesForPlayerScroll = 5
|
|
elseif (linesForPlayerScroll > 10) then
|
|
linesForPlayerScroll = 10
|
|
end
|
|
|
|
local selectedPlayerName = Details:GetActorObjectFromBreakdownWindow():Name()
|
|
lastSelectedPlayerPerSegment[Details:GetCombatFromBreakdownWindow():GetCombatUID()] = selectedPlayerName
|
|
lastSelectedPlayerName = selectedPlayerName
|
|
|
|
local playerLineHeight = player_line_height+1 --the +1 is the space between the lines
|
|
|
|
--recalculate the height free, now that we know the amount of lines the player scroll will show
|
|
heightFree = heightFree - (linesForPlayerScroll * playerLineHeight)
|
|
local linesForSegmentsScroll = math.floor(heightFree/playerLineHeight)
|
|
|
|
playerScroll:SetNumFramesShown(linesForPlayerScroll) --looks like it is not updating the 'totalLines' at the refresh function
|
|
playerScroll:SetHeight(linesForPlayerScroll * playerLineHeight)
|
|
|
|
segmentsScroll:SetNumFramesShown(linesForSegmentsScroll)
|
|
segmentsScroll:SetHeight(linesForSegmentsScroll * playerLineHeight)
|
|
|
|
playerScroll:SetData(playerList)
|
|
playerScroll:Refresh()
|
|
playerScroll:Show()
|
|
|
|
---@type breakdownsegmentdata[]
|
|
local segmentsData = {}
|
|
|
|
---@type combat[]
|
|
local segmentsTable = Details:GetCombatSegments()
|
|
|
|
for i = 1, #segmentsTable do
|
|
---@type combat
|
|
local combatObject = segmentsTable[i]
|
|
|
|
---@type uniquecombatid
|
|
local UID = combatObject:GetCombatUID()
|
|
|
|
local combatName, r, g, b = combatObject:GetCombatName(true)
|
|
local combatIcon, categoryIcon = combatObject:GetCombatIcon()
|
|
|
|
segmentsData[i] = {
|
|
UID = UID,
|
|
combatName = combatName,
|
|
combatIcon = combatIcon,
|
|
r = r or 1,
|
|
g = g or 1,
|
|
b = b or 1,
|
|
}
|
|
end
|
|
|
|
segmentsScroll:SetData(segmentsData)
|
|
segmentsScroll:Refresh()
|
|
segmentsScroll:Show()
|
|
end
|
|
|
|
function Details:UpdateBreakdownPlayerList()
|
|
--run the update on the next tick
|
|
C_Timer.After(0, updatePlayerAndSegmentsList)
|
|
end
|
|
|
|
breakdownWindowFrame:HookScript("OnShow", function()
|
|
Details:UpdateBreakdownPlayerList()
|
|
end)
|
|
|
|
breakdownWindowFrame:HookScript("OnHide", function()
|
|
for lineIndex, line in ipairs(breakdownWindowFrame.playerScrollBox:GetLines()) do
|
|
line.playerObject = nil
|
|
line.combatObject = nil
|
|
end
|
|
end)
|
|
end
|
|
|
|
function Details.PlayerBreakdown.CreatePlayerListFrame()
|
|
if (not Details.PlayerBreakdown.playerListFrameCreated) then
|
|
breakdownWindowPlayerList.CreatePlayerListFrame()
|
|
Details.PlayerBreakdown.playerListFrameCreated = true
|
|
end
|
|
end
|
|
|
|
function Details222.BreakdownWindow.RefreshScrolls()
|
|
Details:UpdateBreakdownPlayerList()
|
|
end |