You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
732 lines
24 KiB
732 lines
24 KiB
|
|
---@type detailsframework
|
|
local detailsFramework = _G["DetailsFramework"]
|
|
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
|
return
|
|
end
|
|
|
|
local CreateFrame = CreateFrame
|
|
local GetSpellInfo = GetSpellInfo
|
|
local GameTooltip = GameTooltip
|
|
local unpack = unpack
|
|
|
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.SortFunctions)
|
|
---add methods to be used on scrollframes
|
|
---@class df_scrollboxmixin
|
|
detailsFramework.ScrollBoxFunctions = {
|
|
--set a function to run right before the refresh function (scroll:Refresh())
|
|
--this function receives the same parameters as the refresh function
|
|
SetPreRefreshFunction = function(self, func)
|
|
self.pre_refresh_func = func
|
|
end,
|
|
|
|
---refresh the scrollbox by resetting all lines created with :CreateLine(), then calling the refresh_func which was set at :CreateScrollBox()
|
|
---@param self table
|
|
---@return table
|
|
Refresh = function(self)
|
|
--hide all frames and tag as not in use
|
|
self._LinesInUse = 0
|
|
for index, frame in ipairs(self.Frames) do
|
|
if (not self.DontHideChildrenOnPreRefresh) then
|
|
frame:Hide()
|
|
end
|
|
frame._InUse = nil
|
|
end
|
|
|
|
local offset = 0
|
|
if (self.IsFauxScroll) then
|
|
self:UpdateFaux(#self.data, self.LineAmount, self.LineHeight)
|
|
offset = self:GetOffsetFaux()
|
|
end
|
|
|
|
if (self.pre_refresh_func) then
|
|
detailsFramework:Dispatch(self.pre_refresh_func, self, self.data, offset, self.LineAmount)
|
|
end
|
|
|
|
--call the refresh function
|
|
detailsFramework:Dispatch(self.refresh_func, self, self.data, offset, self.LineAmount)
|
|
|
|
--hide all frames that are not in use
|
|
for index, frame in ipairs(self.Frames) do
|
|
--the member _InUse is true when the line is used by the refresh function
|
|
--this member is set to true when the code calls scrollBox:GetLine(index)
|
|
if (not frame._InUse) then
|
|
frame:Hide()
|
|
else
|
|
frame:Show()
|
|
end
|
|
end
|
|
|
|
self:Show()
|
|
|
|
local frameName = self:GetName()
|
|
if (frameName) then
|
|
if (self.HideScrollBar) then
|
|
local scrollBar = _G[frameName .. "ScrollBar"]
|
|
if (scrollBar) then
|
|
scrollBar:Hide()
|
|
end
|
|
else
|
|
--[=[ --maybe in the future I visit this again
|
|
local scrollBar = _G[frameName .. "ScrollBar"]
|
|
local height = self:GetHeight()
|
|
local totalLinesRequired = #self.data
|
|
local linesShown = self._LinesInUse
|
|
|
|
local percent = linesShown / totalLinesRequired
|
|
local thumbHeight = height * percent
|
|
scrollBar.ThumbTexture:SetSize(12, thumbHeight)
|
|
print("thumbHeight:", thumbHeight)
|
|
--]=]
|
|
end
|
|
end
|
|
return self.Frames
|
|
end,
|
|
|
|
OnVerticalScroll = function(self, offset)
|
|
self:OnVerticalScrollFaux(offset, self.LineHeight, self.Refresh)
|
|
return true
|
|
end,
|
|
|
|
---create a line within the scrollbox
|
|
---@param self table is the scrollbox
|
|
---@param func function|nil function to create the line object, this function will receive the line index as argument and return a table with the line object
|
|
---@return table line object (table)
|
|
CreateLine = function(self, func)
|
|
if (not func) then
|
|
func = self.CreateLineFunc
|
|
end
|
|
|
|
local okay, newLine = xpcall(func, geterrorhandler(), self, #self.Frames+1)
|
|
if (okay) then
|
|
if (not newLine) then
|
|
error("ScrollFrame:CreateLine() function did not returned a line, use: 'return line'")
|
|
end
|
|
table.insert(self.Frames, newLine)
|
|
newLine.Index = #self.Frames
|
|
return newLine
|
|
end
|
|
return newLine
|
|
end,
|
|
|
|
CreateLines = function(self, callback, lineAmount)
|
|
for i = 1, lineAmount do
|
|
self:CreateLine(callback)
|
|
end
|
|
end,
|
|
|
|
GetLine = function(self, lineIndex)
|
|
local line = self.Frames[lineIndex]
|
|
if (line) then
|
|
line._InUse = true
|
|
end
|
|
|
|
self._LinesInUse = self._LinesInUse + 1
|
|
return line
|
|
end,
|
|
|
|
SetData = function(self, data)
|
|
self.data = data
|
|
if (self.OnSetData) then
|
|
detailsFramework:CoreDispatch((self:GetName() or "ScrollBox") .. ":OnSetData()", self.OnSetData, self, self.data)
|
|
end
|
|
end,
|
|
|
|
GetData = function(self)
|
|
return self.data
|
|
end,
|
|
|
|
GetFrames = function(self)
|
|
return self.Frames
|
|
end,
|
|
|
|
GetLines = function(self) --alias of GetFrames
|
|
return self.Frames
|
|
end,
|
|
|
|
GetNumFramesCreated = function(self)
|
|
return #self.Frames
|
|
end,
|
|
|
|
GetNumFramesShown = function(self)
|
|
return self.LineAmount
|
|
end,
|
|
|
|
SetNumFramesShown = function(self, newAmount)
|
|
--hide frames which won't be used
|
|
if (newAmount < #self.Frames) then
|
|
for i = newAmount+1, #self.Frames do
|
|
self.Frames[i]:Hide()
|
|
end
|
|
end
|
|
--set the new amount
|
|
self.LineAmount = newAmount
|
|
end,
|
|
|
|
SetFramesHeight = function(self, height)
|
|
self.LineHeight = height
|
|
self:OnSizeChanged()
|
|
self:Refresh()
|
|
end,
|
|
|
|
OnSizeChanged = function(self)
|
|
if (self.ReajustNumFrames) then
|
|
--how many lines the scroll can show
|
|
local amountOfFramesToShow = math.floor(self:GetHeight() / self.LineHeight)
|
|
|
|
--how many lines the scroll already have
|
|
local totalFramesCreated = self:GetNumFramesCreated()
|
|
|
|
--how many lines are current shown
|
|
local totalFramesShown = self:GetNumFramesShown()
|
|
|
|
--the amount of frames increased
|
|
if (amountOfFramesToShow > totalFramesShown) then
|
|
for i = totalFramesShown+1, amountOfFramesToShow do
|
|
--check if need to create a new line
|
|
if (i > totalFramesCreated) then
|
|
self:CreateLine(self.CreateLineFunc)
|
|
end
|
|
end
|
|
|
|
--the amount of frames decreased
|
|
elseif (amountOfFramesToShow < totalFramesShown) then
|
|
--hide all frames above the new amount to show
|
|
for i = totalFramesCreated, amountOfFramesToShow, -1 do
|
|
if (self.Frames[i]) then
|
|
self.Frames[i]:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
--set the new amount of frames
|
|
self:SetNumFramesShown(amountOfFramesToShow)
|
|
--refresh lines
|
|
self:Refresh()
|
|
end
|
|
end,
|
|
|
|
--moved functions from blizzard faux scroll that are called from insecure code environment
|
|
--this reduces the amount of taints while using the faux scroll frame
|
|
GetOffsetFaux = function(self)
|
|
return self.offset or 0
|
|
end,
|
|
|
|
OnVerticalScrollFaux = function(self, value, lineHeight, updateFunction)
|
|
local scrollbar = self:GetChildFramesFaux()
|
|
scrollbar:SetValue(value)
|
|
self.offset = math.floor((value / lineHeight) + 0.5)
|
|
|
|
if (updateFunction) then
|
|
updateFunction(self)
|
|
end
|
|
end,
|
|
|
|
GetChildFramesFaux = function(frame)
|
|
local frameName = frame:GetName();
|
|
if frameName then
|
|
return _G[ frameName.."ScrollBar" ], _G[ frameName.."ScrollChildFrame" ], _G[ frameName.."ScrollBarScrollUpButton" ], _G[ frameName.."ScrollBarScrollDownButton" ];
|
|
else
|
|
return frame.ScrollBar, frame.ScrollChildFrame, frame.ScrollBar.ScrollUpButton, frame.ScrollBar.ScrollDownButton;
|
|
end
|
|
end,
|
|
|
|
UpdateFaux = function(frame, numItems, numToDisplay, buttonHeight, button, smallWidth, bigWidth, highlightFrame, smallHighlightWidth, bigHighlightWidth, alwaysShowScrollBar)
|
|
local scrollBar, scrollChildFrame, scrollUpButton, scrollDownButton = frame:GetChildFramesFaux();
|
|
-- If more than one screen full of items then show the scrollbar
|
|
local showScrollBar;
|
|
if ( numItems > numToDisplay or alwaysShowScrollBar ) then
|
|
frame:Show();
|
|
showScrollBar = 1;
|
|
else
|
|
scrollBar:SetValue(0);
|
|
frame:Hide();
|
|
end
|
|
if ( frame:IsShown() ) then
|
|
local scrollFrameHeight = 0;
|
|
local scrollChildHeight = 0;
|
|
|
|
if ( numItems > 0 ) then
|
|
scrollFrameHeight = (numItems - numToDisplay) * buttonHeight;
|
|
scrollChildHeight = numItems * buttonHeight;
|
|
if ( scrollFrameHeight < 0 ) then
|
|
scrollFrameHeight = 0;
|
|
end
|
|
scrollChildFrame:Show();
|
|
else
|
|
scrollChildFrame:Hide();
|
|
end
|
|
local maxRange = (numItems - numToDisplay) * buttonHeight;
|
|
if (maxRange < 0) then
|
|
maxRange = 0;
|
|
end
|
|
scrollBar:SetMinMaxValues(0, maxRange);
|
|
scrollBar:SetValueStep(buttonHeight);
|
|
scrollBar:SetStepsPerPage(numToDisplay-1);
|
|
scrollChildFrame:SetHeight(scrollChildHeight);
|
|
|
|
-- Arrow button handling
|
|
if ( scrollBar:GetValue() == 0 ) then
|
|
scrollUpButton:Disable();
|
|
else
|
|
scrollUpButton:Enable();
|
|
end
|
|
if ((scrollBar:GetValue() - scrollFrameHeight) == 0) then
|
|
scrollDownButton:Disable();
|
|
else
|
|
scrollDownButton:Enable();
|
|
end
|
|
|
|
-- Shrink because scrollbar is shown
|
|
if ( highlightFrame ) then
|
|
highlightFrame:SetWidth(smallHighlightWidth);
|
|
end
|
|
if ( button ) then
|
|
for i=1, numToDisplay do
|
|
_G[button..i]:SetWidth(smallWidth);
|
|
end
|
|
end
|
|
else
|
|
-- Widen because scrollbar is hidden
|
|
if ( highlightFrame ) then
|
|
highlightFrame:SetWidth(bigHighlightWidth);
|
|
end
|
|
if ( button ) then
|
|
for i=1, numToDisplay do
|
|
_G[button..i]:SetWidth(bigWidth);
|
|
end
|
|
end
|
|
end
|
|
|
|
return showScrollBar;
|
|
end,
|
|
}
|
|
|
|
|
|
---@class df_gridscrollbox_options : table
|
|
---@field width number?
|
|
---@field height number?
|
|
---@field line_amount number?
|
|
---@field line_height number?
|
|
---@field columns_per_line number?
|
|
---@field auto_amount boolean?
|
|
---@field no_scroll boolean?
|
|
---@field vertical_padding number?
|
|
---@field no_backdrop boolean?
|
|
|
|
---@type df_gridscrollbox_options
|
|
local grid_scrollbox_options = {
|
|
width = 600,
|
|
height = 400,
|
|
line_amount = 10,
|
|
line_height = 30,
|
|
columns_per_line = 4,
|
|
no_scroll = false,
|
|
vertical_padding = 1,
|
|
no_backdrop = false,
|
|
}
|
|
|
|
---@class df_gridscrollbox : df_scrollbox
|
|
|
|
---create a scrollbox with a grid layout
|
|
---@param parent frame
|
|
---@param name string
|
|
---@param refreshFunc function
|
|
---@param data table
|
|
---@param createColumnFrameFunc function
|
|
---@param options df_gridscrollbox_options?
|
|
---@return unknown
|
|
function detailsFramework:CreateGridScrollBox(parent, name, refreshFunc, data, createColumnFrameFunc, options)
|
|
options = options or {}
|
|
|
|
--check values passed, get defaults and cast values due to the scrollbox require some values to be numbers
|
|
local width = type(options.width) == "number" and options.width or grid_scrollbox_options.width
|
|
---@cast width number
|
|
|
|
local height = type(options.height) == "number" and options.height or grid_scrollbox_options.height
|
|
---@cast height number
|
|
|
|
local lineAmount = type(options.line_amount) == "number" and options.line_amount or grid_scrollbox_options.line_amount
|
|
---@cast lineAmount number
|
|
|
|
local lineHeight = type(options.line_height) == "number" and options.line_height or grid_scrollbox_options.line_height
|
|
---@cast lineHeight number
|
|
|
|
local columnsPerLine = options.columns_per_line or grid_scrollbox_options.columns_per_line
|
|
local autoAmount = options.auto_amount
|
|
local noScroll = options.no_scroll
|
|
local noBackdrop = options.no_backdrop
|
|
local verticalPadding = options.vertical_padding or grid_scrollbox_options.vertical_padding
|
|
|
|
local createLineFunc = function(scrollBox, lineIndex)
|
|
local line = CreateFrame("frame", "$parentLine" .. lineIndex, scrollBox)
|
|
line:SetSize(width, lineHeight)
|
|
line:SetPoint("top", scrollBox, "top", 0, -((lineIndex-1) * (lineHeight + verticalPadding)))
|
|
line.optionFrames = {}
|
|
|
|
for columnIndex = 1, columnsPerLine do
|
|
--dispatch payload: line, lineIndex, columnIndex
|
|
local optionFrame = createColumnFrameFunc(line, lineIndex, columnIndex)
|
|
line.optionFrames[columnIndex] = optionFrame
|
|
optionFrame:SetPoint("left", line, "left", (columnIndex-1) * (width/columnsPerLine), 0)
|
|
end
|
|
|
|
return line
|
|
end
|
|
|
|
local onSetData = function(self, data)
|
|
local newData = {}
|
|
|
|
for i = 1, #data, columnsPerLine do
|
|
local thisColumnData = {}
|
|
|
|
for o = 1, columnsPerLine do
|
|
local index = i + (o-1)
|
|
local thisData = data[index]
|
|
if (thisData) then
|
|
thisColumnData[#thisColumnData+1] = thisData
|
|
end
|
|
end
|
|
newData[#newData+1] = thisColumnData
|
|
end
|
|
|
|
self.data = newData
|
|
end
|
|
|
|
local refreshGrid = function(scrollBox, thisData, offset, totalLines)
|
|
for i = 1, totalLines do
|
|
local index = i + offset
|
|
local lineData = thisData[index]
|
|
|
|
if (lineData) then
|
|
local line = scrollBox:GetLine(i)
|
|
for o = 1, columnsPerLine do
|
|
local optionFrame = line.optionFrames[o]
|
|
local data = lineData[o]
|
|
if (data) then
|
|
detailsFramework:Dispatch(refreshFunc, optionFrame, data)
|
|
optionFrame:Show()
|
|
line:Show()
|
|
else
|
|
optionFrame:Hide()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (not name) then
|
|
name = "DetailsFrameworkAuraScrollBox" .. math.random(1, 9999999)
|
|
end
|
|
|
|
local scrollBox = detailsFramework:CreateScrollBox(parent, name, refreshGrid, data, width, height, lineAmount, lineHeight, createLineFunc, autoAmount, noScroll, noBackdrop)
|
|
scrollBox:CreateLines(createLineFunc, lineAmount)
|
|
detailsFramework:ReskinSlider(scrollBox)
|
|
scrollBox.OnSetData = onSetData
|
|
onSetData(scrollBox, data)
|
|
|
|
return scrollBox
|
|
end
|
|
|
|
--Need to test this and check the "same_name_spells_add(value)" on the OnEnter function
|
|
--also need to make sure this can work with any data (global, class, spec) and aura type (buff, debuff)
|
|
|
|
--aura scroll box
|
|
---@class df_aurascrollbox_options : table
|
|
---@field line_height number?
|
|
---@field line_amount number?
|
|
---@field width number?
|
|
---@field height number?
|
|
---@field vertical_padding number?
|
|
---@field show_spell_tooltip boolean
|
|
---@field remove_icon_border boolean
|
|
---@field no_scroll boolean
|
|
---@field no_backdrop boolean
|
|
---@field backdrop_onenter number[]?
|
|
---@field backdrop_onleave number[]?
|
|
---@field font_size number?
|
|
---@field title_text string?
|
|
|
|
local auraScrollDefaultSettings = {
|
|
line_height = 18,
|
|
line_amount = 18,
|
|
width = 300,
|
|
height = 500,
|
|
vertical_padding = 1,
|
|
show_spell_tooltip = false,
|
|
remove_icon_border = true,
|
|
no_scroll = false,
|
|
no_backdrop = false,
|
|
backdrop_onenter = {.8, .8, .8, 0.4},
|
|
backdrop_onleave = {.8, .8, .8, 0.2},
|
|
font_size = 12,
|
|
title_text = "",
|
|
}
|
|
|
|
---@param parent frame
|
|
---@param name string?
|
|
---@param data table? --can be set later with :SetData()
|
|
---@param onAuraRemoveCallback function?
|
|
---@param options df_aurascrollbox_options?
|
|
function detailsFramework:CreateAuraScrollBox(parent, name, data, onAuraRemoveCallback, options)
|
|
--hack the construction of the options table here, as the scrollbox is created much later
|
|
options = options or {}
|
|
local scrollOptions = {}
|
|
detailsFramework.OptionsFunctions.BuildOptionsTable(scrollOptions, auraScrollDefaultSettings, options)
|
|
options = scrollOptions.options
|
|
|
|
local refreshAuraLines = function(self, data, offset, totalLines)
|
|
for i = 1, totalLines do
|
|
local index = i + offset
|
|
local auraTable = data[index]
|
|
if (auraTable) then
|
|
local line = self:GetLine(i)
|
|
local spellId, spellName, spellIcon, lowerSpellName, bAddedBySpellName = unpack(auraTable)
|
|
|
|
line.SpellID = spellId
|
|
line.SpellName = spellName
|
|
line.SpellNameLower = lowerSpellName
|
|
line.SpellIcon = spellIcon
|
|
line.Flag = bAddedBySpellName
|
|
|
|
if (bAddedBySpellName) then
|
|
line.name:SetText(spellName)
|
|
else
|
|
line.name:SetText(spellName .. " (" .. spellId .. ")")
|
|
end
|
|
|
|
line.icon:SetTexture(spellIcon)
|
|
if (options.remove_icon_border) then
|
|
line.icon:SetTexCoord(.1, .9, .1, .9)
|
|
else
|
|
line.icon:SetTexCoord(0, 1, 0, 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local onLeaveAuraLine = function(self)
|
|
self:SetBackdropColor(unpack(options.backdrop_onleave))
|
|
GameTooltip:Hide()
|
|
GameCooltip:Hide()
|
|
end
|
|
|
|
local onEnterAuraLine = function(line)
|
|
if (options.show_spell_tooltip and line.SpellID and GetSpellInfo(line.SpellID)) then
|
|
GameTooltip:SetOwner(line, "ANCHOR_CURSOR")
|
|
GameTooltip:SetSpellByID(line.SpellID)
|
|
GameTooltip:AddLine(" ")
|
|
GameTooltip:Show()
|
|
end
|
|
line:SetBackdropColor(unpack(options.backdrop_onenter))
|
|
|
|
local bTrackByName = line.Flag --the user entered the spell name to track the spell (and not a spellId)
|
|
local spellId = line.SpellID
|
|
|
|
if (bTrackByName) then --the user entered the spell name to track the spell
|
|
local spellsHashMap, spellsIndexTable, spellsWithSameName = detailsFramework:GetSpellCaches()
|
|
if (spellsWithSameName) then
|
|
local spellName, _, spellIcon = GetSpellInfo(spellId)
|
|
if (spellName) then
|
|
local spellNameLower = spellName:lower()
|
|
local sameNameSpells = spellsWithSameName[spellNameLower]
|
|
|
|
if (sameNameSpells) then
|
|
GameCooltip:Preset(2)
|
|
GameCooltip:SetOwner(line, "left", "right", 2, 0)
|
|
GameCooltip:SetOption("TextSize", 10)
|
|
|
|
for i, thisSpellId in ipairs(sameNameSpells) do
|
|
GameCooltip:AddLine(spellName .. " (" .. thisSpellId .. ")")
|
|
GameCooltip:AddIcon(spellIcon, 1, 1, 14, 14, .1, .9, .1, .9)
|
|
end
|
|
|
|
GameCooltip:Show()
|
|
end
|
|
end
|
|
end
|
|
|
|
else --the user entered the spellId to track the spell
|
|
GameCooltip:Preset(2)
|
|
GameCooltip:SetOwner(line, "left", "right", 2, 0)
|
|
GameCooltip:SetOption("TextSize", 10)
|
|
|
|
local spellName, _, spellIcon = GetSpellInfo(spellId)
|
|
if (spellName) then
|
|
GameCooltip:AddLine(spellName .. " (" .. spellId .. ")")
|
|
GameCooltip:AddIcon(spellIcon, 1, 1, 14, 14, .1, .9, .1, .9)
|
|
end
|
|
GameCooltip:Show()
|
|
end
|
|
end
|
|
|
|
local onClickAuraRemoveButton = function(self)
|
|
local spellId = tonumber(self:GetParent().SpellID)
|
|
if (spellId and type(spellId) == "number") then
|
|
--button > line > scrollbox
|
|
local scrollBox = self:GetParent():GetParent()
|
|
scrollBox.data_original[spellId] = nil
|
|
scrollBox.data_original["" .. (spellId or "")] = nil -- cleanup...
|
|
|
|
scrollBox:TransformAuraData()
|
|
scrollBox:Refresh()
|
|
|
|
if (onAuraRemoveCallback) then --upvalue
|
|
detailsFramework:QuickDispatch(onAuraRemoveCallback, spellId)
|
|
end
|
|
end
|
|
end
|
|
|
|
local createLineFunc = function(self, index)
|
|
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
|
local scrollBoxWidth = options.width
|
|
local lineHeight = options.line_height
|
|
local verticalPadding = options.vertical_padding
|
|
|
|
line:SetPoint("topleft", self, "topleft", 1, -((index-1) * (lineHeight + verticalPadding)) - 1)
|
|
line:SetSize(scrollBoxWidth - 2, lineHeight)
|
|
line:SetScript("OnEnter", onEnterAuraLine)
|
|
line:SetScript("OnLeave", onLeaveAuraLine)
|
|
|
|
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
|
line:SetBackdropColor(unpack(options.backdrop_onleave))
|
|
|
|
local iconTexture = line:CreateTexture("$parentIcon", "overlay")
|
|
iconTexture:SetSize(lineHeight - 2, lineHeight - 2)
|
|
|
|
local spellNameFontString = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
|
detailsFramework:SetFontSize(spellNameFontString, options.font_size)
|
|
|
|
local removeButton = CreateFrame("button", "$parentRemoveButton", line, "UIPanelCloseButton")
|
|
removeButton:SetSize(16, 16)
|
|
removeButton:SetScript("OnClick", onClickAuraRemoveButton)
|
|
removeButton:SetPoint("topright", line, "topright", 0, 0)
|
|
removeButton:GetNormalTexture():SetDesaturated(true)
|
|
|
|
iconTexture:SetPoint("left", line, "left", 2, 0)
|
|
spellNameFontString:SetPoint("left", iconTexture, "right", 3, 0)
|
|
|
|
line.icon = iconTexture
|
|
line.name = spellNameFontString
|
|
line.removebutton = removeButton
|
|
|
|
return line
|
|
end
|
|
|
|
---@class df_aurascrollbox : df_scrollbox
|
|
---@field data_original table
|
|
---@field refresh_original function
|
|
---@field TitleLabel fontstring
|
|
---@field TransformAuraData fun(self:df_aurascrollbox)
|
|
---@field GetTitleFontString fun(self:df_aurascrollbox): fontstring
|
|
|
|
data = data or {}
|
|
|
|
if (not name) then
|
|
name = "DetailsFrameworkAuraScrollBox" .. math.random(1, 9999999)
|
|
end
|
|
|
|
local auraScrollBox = detailsFramework:CreateScrollBox(parent, name, refreshAuraLines, data, options.width, options.height, options.line_amount, options.line_height)
|
|
detailsFramework:ReskinSlider(auraScrollBox)
|
|
---@cast auraScrollBox df_aurascrollbox
|
|
auraScrollBox.data_original = data
|
|
|
|
local titleLabel = auraScrollBox:CreateFontString("$parentTitleLabel", "overlay", "GameFontNormal")
|
|
titleLabel:SetPoint("bottomleft", auraScrollBox, "topleft", 0, 2)
|
|
detailsFramework:SetFontColor(titleLabel, "silver")
|
|
detailsFramework:SetFontSize(titleLabel, 10)
|
|
auraScrollBox.TitleLabel = titleLabel
|
|
|
|
function auraScrollBox:GetTitleFontString()
|
|
return self.TitleLabel
|
|
end
|
|
|
|
for i = 1, options.line_amount do
|
|
auraScrollBox:CreateLine(createLineFunc)
|
|
end
|
|
|
|
function auraScrollBox:TransformAuraData()
|
|
local newData = {}
|
|
local added = {}
|
|
|
|
for spellId, bAddedBySpellName in pairs(self.data_original) do
|
|
local spellName, _, spellIcon = GetSpellInfo(spellId)
|
|
if (spellName and not added[tonumber(spellId) or 0]) then
|
|
local lowerSpellName = spellName:lower()
|
|
table.insert(newData, {spellId, spellName, spellIcon, lowerSpellName, bAddedBySpellName})
|
|
added[tonumber(spellId) or 0] = true
|
|
end
|
|
end
|
|
|
|
table.sort(newData, function(t1, t2) return t1[4] < t2[4] end)
|
|
self.data = newData
|
|
end
|
|
|
|
auraScrollBox.SetData = function(self, data)
|
|
self.data_original = data
|
|
self.data = data
|
|
auraScrollBox:TransformAuraData()
|
|
end
|
|
|
|
auraScrollBox.GetData = function(self)
|
|
return self.data_original
|
|
end
|
|
|
|
auraScrollBox.refresh_original = auraScrollBox.Refresh
|
|
|
|
auraScrollBox.Refresh = function()
|
|
auraScrollBox:TransformAuraData()
|
|
auraScrollBox:refresh_original()
|
|
end
|
|
|
|
auraScrollBox:SetData(data)
|
|
|
|
return auraScrollBox
|
|
end
|
|
|
|
|
|
detailsFramework.CanvasScrollBoxMixin = {
|
|
|
|
}
|
|
|
|
local canvasScrollBoxDefaultOptions = {
|
|
width = 600,
|
|
height = 400,
|
|
reskin_slider = true,
|
|
}
|
|
|
|
---@class df_canvasscrollbox : scrollframe, df_optionsmixin
|
|
---@field child frame
|
|
|
|
---@param parent frame
|
|
---@param child frame?
|
|
---@param name string?
|
|
---@param options table?
|
|
---@return df_canvasscrollbox
|
|
function detailsFramework:CreateCanvasScrollBox(parent, child, name, options)
|
|
---@type df_canvasscrollbox
|
|
local canvasScrollBox = CreateFrame("scrollframe", name or ("DetailsFrameworkCanvasScroll" .. math.random(50000, 10000000)), parent, "BackdropTemplate, UIPanelScrollFrameTemplate")
|
|
|
|
detailsFramework:Mixin(canvasScrollBox, detailsFramework.CanvasScrollBoxMixin)
|
|
detailsFramework:Mixin(canvasScrollBox, detailsFramework.OptionsFunctions)
|
|
|
|
options = options or {}
|
|
canvasScrollBox:BuildOptionsTable(canvasScrollBoxDefaultOptions, options)
|
|
|
|
canvasScrollBox:SetSize(canvasScrollBox.options.width, canvasScrollBox.options.height)
|
|
|
|
if (not child) then
|
|
child = CreateFrame("frame", "$parentChild", canvasScrollBox)
|
|
end
|
|
|
|
canvasScrollBox:SetScrollChild(child)
|
|
canvasScrollBox:EnableMouseWheel(true)
|
|
|
|
canvasScrollBox.child = child
|
|
|
|
if (canvasScrollBox.options.reskin_slider) then
|
|
detailsFramework:ReskinSlider(canvasScrollBox)
|
|
end
|
|
|
|
return canvasScrollBox
|
|
end
|