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.
966 lines
28 KiB
966 lines
28 KiB
|
|
local detailsFramework = _G["DetailsFramework"]
|
|
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
|
return
|
|
end
|
|
|
|
local _
|
|
|
|
local getFrame = function(frame)
|
|
return rawget(frame, "widget") or frame
|
|
end
|
|
|
|
detailsFramework.WidgetFunctions = {
|
|
GetCapsule = function(self)
|
|
return self.MyObject
|
|
end,
|
|
|
|
GetObject = function(self)
|
|
return self.MyObject
|
|
end,
|
|
}
|
|
|
|
detailsFramework.DefaultMetaFunctionsGet = {
|
|
parent = function(object)
|
|
return object:GetParent()
|
|
end,
|
|
|
|
shown = function(object)
|
|
return object:IsShown()
|
|
end,
|
|
}
|
|
|
|
detailsFramework.TooltipHandlerMixin = {
|
|
SetTooltip = function(self, tooltip)
|
|
if (tooltip) then
|
|
if (detailsFramework.Language.IsLocTable(tooltip)) then
|
|
--register the locTable as a tableKey
|
|
local locTable = tooltip
|
|
detailsFramework.Language.RegisterTableKeyWithLocTable(self, "have_tooltip", locTable)
|
|
else
|
|
self.have_tooltip = tooltip
|
|
end
|
|
else
|
|
self.have_tooltip = nil
|
|
end
|
|
end,
|
|
|
|
GetTooltip = function(self)
|
|
return self.have_tooltip
|
|
end,
|
|
|
|
ShowTooltip = function(self)
|
|
local tooltipText = self:GetTooltip()
|
|
|
|
if (type(tooltipText) == "function") then
|
|
local tooltipFunction = tooltipText
|
|
local gotTooltip, tooltipString = xpcall(tooltipFunction, geterrorhandler())
|
|
if (gotTooltip) then
|
|
tooltipText = tooltipString
|
|
end
|
|
end
|
|
|
|
if (tooltipText and tooltipText ~= "") then
|
|
GameCooltip:Preset(2)
|
|
GameCooltip:AddLine(tooltipText)
|
|
GameCooltip:ShowRoundedCorner()
|
|
GameCooltip:ShowCooltip(getFrame(self), "tooltip")
|
|
end
|
|
end,
|
|
|
|
HideTooltip = function(self)
|
|
local tooltipText = self:GetTooltip()
|
|
if (tooltipText) then
|
|
if (GameCooltip:IsOwner(getFrame(self))) then
|
|
GameCooltip:Hide()
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
|
|
detailsFramework.DefaultMetaFunctionsSet = {
|
|
parent = function(object, value)
|
|
return object:SetParent(value)
|
|
end,
|
|
|
|
show = function(object, value)
|
|
if (value) then
|
|
return object:Show()
|
|
else
|
|
return object:Hide()
|
|
end
|
|
end,
|
|
|
|
hide = function(object, value)
|
|
if (value) then
|
|
return object:Hide()
|
|
else
|
|
return object:Show()
|
|
end
|
|
end,
|
|
}
|
|
|
|
detailsFramework.DefaultMetaFunctionsSet.shown = detailsFramework.DefaultMetaFunctionsSet.show
|
|
|
|
detailsFramework.LayeredRegionMetaFunctionsSet = {
|
|
drawlayer = function(object, value)
|
|
object.image:SetDrawLayer(value)
|
|
end,
|
|
|
|
sublevel = function(object, value)
|
|
local drawLayer = object:GetDrawLayer()
|
|
object:SetDrawLayer(drawLayer, value)
|
|
end,
|
|
}
|
|
|
|
detailsFramework.LayeredRegionMetaFunctionsGet = {
|
|
drawlayer = function(object)
|
|
return object.image:GetDrawLayer()
|
|
end,
|
|
|
|
sublevel = function(object)
|
|
local _, subLevel = object.image:GetDrawLayer()
|
|
return subLevel
|
|
end,
|
|
}
|
|
|
|
detailsFramework.FrameMixin = {
|
|
SetFrameStrata = function(self, strata)
|
|
self = getFrame(self)
|
|
if (type(strata) == "table" and strata.GetObjectType) then
|
|
local UIObject = strata
|
|
self:SetFrameStrata(UIObject:GetFrameStrata())
|
|
else
|
|
self:SetFrameStrata(strata)
|
|
end
|
|
end,
|
|
|
|
SetFrameLevel = function(self, level, UIObject)
|
|
self = getFrame(self)
|
|
if (not UIObject) then
|
|
self:SetFrameLevel(level)
|
|
else
|
|
local framelevel = UIObject:GetFrameLevel(UIObject) + level
|
|
self:SetFrameLevel(framelevel)
|
|
end
|
|
end,
|
|
|
|
SetSize = function(self, width, height)
|
|
self = getFrame(self)
|
|
if (width) then
|
|
self:SetWidth(width)
|
|
end
|
|
if (height) then
|
|
self:SetHeight(height)
|
|
end
|
|
end,
|
|
|
|
SetBackdrop = function(self, ...)
|
|
self = getFrame(self)
|
|
self:SetBackdrop(...)
|
|
end,
|
|
|
|
SetBackdropColor = function(self, ...)
|
|
self = getFrame(self)
|
|
self:SetBackdropColor(...)
|
|
end,
|
|
|
|
SetBackdropBorderColor = function(self, ...)
|
|
self = getFrame(self)
|
|
self:SetBackdropBorderColor(...)
|
|
end,
|
|
}
|
|
|
|
local doublePoint = {
|
|
["lefts"] = true,
|
|
["rights"] = true,
|
|
["tops"] = true,
|
|
["bottoms"] = true,
|
|
|
|
["left-left"] = true,
|
|
["right-right"] = true,
|
|
["top-top"] = true,
|
|
["bottom-bottom"] = true,
|
|
|
|
["bottom-top"] = true,
|
|
["top-bottom"] = true,
|
|
["right-left"] = true,
|
|
["left-right"] = true,
|
|
}
|
|
|
|
detailsFramework.SetPointMixin = {
|
|
SetPoint = function(object, anchorName1, anchorObject, anchorName2, xOffset, yOffset)
|
|
if (doublePoint[anchorName1]) then
|
|
object:ClearAllPoints()
|
|
local anchorTo
|
|
if (anchorObject and type(anchorObject) == "table") then
|
|
xOffset, yOffset = anchorName2 or 0, xOffset or 0
|
|
anchorTo = getFrame(anchorObject)
|
|
else
|
|
xOffset, yOffset = anchorObject or 0, anchorName2 or 0
|
|
anchorTo = object:GetParent()
|
|
end
|
|
|
|
--offset always inset to inner
|
|
if (anchorName1 == "lefts") then
|
|
object:SetPoint("topleft", anchorTo, "topleft", xOffset, -yOffset)
|
|
object:SetPoint("bottomleft", anchorTo, "bottomleft", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "rights") then
|
|
object:SetPoint("topright", anchorTo, "topright", xOffset, -yOffset)
|
|
object:SetPoint("bottomright", anchorTo, "bottomright", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "tops") then
|
|
object:SetPoint("topleft", anchorTo, "topleft", xOffset, -yOffset)
|
|
object:SetPoint("topright", anchorTo, "topright", -xOffset, -yOffset)
|
|
|
|
elseif (anchorName1 == "bottoms") then
|
|
object:SetPoint("bottomleft", anchorTo, "bottomleft", xOffset, yOffset)
|
|
object:SetPoint("bottomright", anchorTo, "bottomright", -xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "left-left") then
|
|
object:SetPoint("left", anchorTo, "left", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "right-right") then
|
|
object:SetPoint("right", anchorTo, "right", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "top-top") then
|
|
object:SetPoint("top", anchorTo, "top", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "bottom-bottom") then
|
|
object:SetPoint("bottom", anchorTo, "bottom", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "bottom-top") then
|
|
object:SetPoint("bottomleft", anchorTo, "topleft", xOffset, yOffset)
|
|
object:SetPoint("bottomright", anchorTo, "topright", -xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "top-bottom") then
|
|
object:SetPoint("topleft", anchorTo, "bottomleft", xOffset, -yOffset)
|
|
object:SetPoint("topright", anchorTo, "bottomright", -xOffset, -yOffset)
|
|
|
|
elseif (anchorName1 == "right-left") then
|
|
object:SetPoint("topright", anchorTo, "topleft", xOffset, -yOffset)
|
|
object:SetPoint("bottomright", anchorTo, "bottomleft", xOffset, yOffset)
|
|
|
|
elseif (anchorName1 == "left-right") then
|
|
object:SetPoint("topleft", anchorTo, "topright", xOffset, -yOffset)
|
|
object:SetPoint("bottomleft", anchorTo, "bottomright", xOffset, yOffset)
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
xOffset = xOffset or 0
|
|
yOffset = yOffset or 0
|
|
|
|
anchorName1, anchorObject, anchorName2, xOffset, yOffset = detailsFramework:CheckPoints(anchorName1, anchorObject, anchorName2, xOffset, yOffset, object)
|
|
if (not anchorName1) then
|
|
error("SetPoint: Invalid parameter.")
|
|
return
|
|
end
|
|
|
|
if (not object.widget) then
|
|
local SetPoint = getmetatable(object).__index.SetPoint
|
|
return SetPoint(object, anchorName1, anchorObject, anchorName2, xOffset, yOffset)
|
|
else
|
|
return object.widget:SetPoint(anchorName1, anchorObject, anchorName2, xOffset, yOffset)
|
|
end
|
|
end,
|
|
}
|
|
|
|
---mixin for options
|
|
---@class df_optionsmixin
|
|
---@field options table
|
|
---@field SetOption fun(self, optionName: string, optionValue: any)
|
|
---@field GetOption fun(self, optionName: string):any
|
|
---@field GetAllOptions fun(self):table
|
|
---@field BuildOptionsTable fun(self, defaultOptions: table, userOptions: table)
|
|
detailsFramework.OptionsFunctions = {
|
|
SetOption = function(self, optionName, optionValue)
|
|
if (self.options) then
|
|
self.options [optionName] = optionValue
|
|
else
|
|
self.options = {}
|
|
self.options [optionName] = optionValue
|
|
end
|
|
|
|
if (self.OnOptionChanged) then
|
|
detailsFramework:Dispatch (self.OnOptionChanged, self, optionName, optionValue)
|
|
end
|
|
end,
|
|
|
|
GetOption = function(self, optionName)
|
|
return self.options and self.options [optionName]
|
|
end,
|
|
|
|
GetAllOptions = function(self)
|
|
if (self.options) then
|
|
local optionsTable = {}
|
|
for key, _ in pairs(self.options) do
|
|
optionsTable [#optionsTable + 1] = key
|
|
end
|
|
return optionsTable
|
|
else
|
|
return {}
|
|
end
|
|
end,
|
|
|
|
BuildOptionsTable = function(self, defaultOptions, userOptions)
|
|
self.options = self.options or {}
|
|
detailsFramework.table.deploy(self.options, userOptions or {})
|
|
detailsFramework.table.deploy(self.options, defaultOptions or {})
|
|
end
|
|
}
|
|
|
|
--payload mixin
|
|
detailsFramework.PayloadMixin = {
|
|
ClearPayload = function(self)
|
|
self.payload = {}
|
|
end,
|
|
|
|
SetPayload = function(self, ...)
|
|
self.payload = {...}
|
|
return self.payload
|
|
end,
|
|
|
|
AddPayload = function(self, ...)
|
|
local currentPayload = self.payload or {}
|
|
self.payload = currentPayload
|
|
|
|
for i = 1, select("#", ...) do
|
|
local value = select(i, ...)
|
|
currentPayload[#currentPayload+1] = value
|
|
end
|
|
|
|
return self.payload
|
|
end,
|
|
|
|
GetPayload = function(self)
|
|
return self.payload
|
|
end,
|
|
|
|
DumpPayload = function(self)
|
|
return unpack(self.payload)
|
|
end,
|
|
|
|
--does not copy wow objects, just pass them to the new table, tables strings and numbers are copied entirely
|
|
DuplicatePayload = function(self)
|
|
local duplicatedPayload = detailsFramework.table.duplicate({}, self.payload)
|
|
return duplicatedPayload
|
|
end,
|
|
}
|
|
|
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.ScriptHookMixin)
|
|
---
|
|
---@class df_scripthookmixin
|
|
---@field HookList table
|
|
---@field SetHook fun(self: table, hookType: string, func: function)
|
|
---@field HasHook fun(self: table, hookType: string, func: function)
|
|
---@field RunHooksForWidget fun(self: table, event: string, ...)
|
|
---@field ClearHooks fun(self: table)
|
|
|
|
detailsFramework.ScriptHookMixin = {
|
|
RunHooksForWidget = function(self, event, ...)
|
|
local hooks = self.HookList[event]
|
|
|
|
if (not hooks) then
|
|
print(self.widget:GetName(), "no hooks for", event)
|
|
return
|
|
end
|
|
|
|
for i, func in ipairs(hooks) do
|
|
local success, canInterrupt = xpcall(func, geterrorhandler(), ...)
|
|
|
|
if (not success) then
|
|
--error("Details! Framework: " .. event .. " hook for " .. self:GetName() .. ": " .. canInterrupt)
|
|
return false
|
|
|
|
elseif (canInterrupt) then
|
|
return true
|
|
end
|
|
end
|
|
end,
|
|
|
|
SetHook = function(self, hookType, func)
|
|
if (self.HookList[hookType]) then
|
|
if (type(func) == "function") then
|
|
local isRemoval = false
|
|
for i = #self.HookList[hookType], 1, -1 do
|
|
if (self.HookList[hookType][i] == func) then
|
|
table.remove(self.HookList[hookType], i)
|
|
isRemoval = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if (not isRemoval) then
|
|
table.insert(self.HookList[hookType], func)
|
|
end
|
|
else
|
|
if (detailsFramework.debug) then
|
|
print(debugstack())
|
|
error("Details! Framework: invalid function for widget " .. self.WidgetType .. ".")
|
|
end
|
|
end
|
|
else
|
|
if (detailsFramework.debug) then
|
|
error("Details! Framework: unknown hook type for widget " .. self.WidgetType .. ": '" .. hookType .. "'.")
|
|
end
|
|
end
|
|
end,
|
|
|
|
HasHook = function(self, hookType, func)
|
|
if (self.HookList[hookType]) then
|
|
if (type(func) == "function") then
|
|
for i = #self.HookList[hookType], 1, -1 do
|
|
if (self.HookList[hookType][i] == func) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
|
|
ClearHooks = function(self)
|
|
for hookType, hookTable in pairs(self.HookList) do
|
|
table.wipe(hookTable)
|
|
end
|
|
end,
|
|
}
|
|
|
|
--back compatibility, can be removed in the future (28/04/2023)
|
|
---@class DetailsFramework.ScrollBoxFunctions : df_scrollboxmixin
|
|
|
|
local SortMember = ""
|
|
local SortByMember = function(t1, t2)
|
|
return t1[SortMember] > t2[SortMember]
|
|
end
|
|
local SortByMemberReverse = function(t1, t2)
|
|
return t1[SortMember] < t2[SortMember]
|
|
end
|
|
|
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.SortFunctions)
|
|
---adds the method Sort() to a table, this method can be used to sort another table by a member, can't sort itself
|
|
|
|
---@class df_sortmixin
|
|
detailsFramework.SortFunctions = {
|
|
---sort a table by a member
|
|
---@param self table
|
|
---@param tThisTable table
|
|
---@param sMemberName string
|
|
---@param bIsReverse boolean
|
|
Sort = function(self, tThisTable, sMemberName, bIsReverse)
|
|
SortMember = sMemberName
|
|
if (not bIsReverse) then
|
|
table.sort(tThisTable, SortByMember)
|
|
else
|
|
table.sort(tThisTable, SortByMemberReverse)
|
|
end
|
|
end
|
|
}
|
|
|
|
---@class df_data : table
|
|
---@field _dataInfo {data: table, dataCurrentIndex: number, callbacks: function[]}
|
|
---@field callbacks table<function, any[]>
|
|
---@field dataCurrentIndex number
|
|
---@field DataConstructor fun(self: df_data)
|
|
---@field AddDataChangeCallback fun(self: df_data, callback: function, ...: any)
|
|
---@field RemoveDataChangeCallback fun(self: df_data, callback: function)
|
|
---@field GetData fun(self: df_data)
|
|
---@field GetDataSize fun(self: df_data) : number
|
|
---@field GetDataFirstValue fun(self: df_data) : any
|
|
---@field GetDataLastValue fun(self: df_data) : any
|
|
---@field GetDataMinMaxValues fun(self: df_data) : number, number
|
|
---@field GetDataMinMaxValueFromSubTable fun(self: df_data, key: string) : number, number when data uses sub tables, get the min max values from a specific index or key, if the value stored is number, return the min and max values
|
|
---@field SetData fun(self: df_data, data: table, anyValue: any)
|
|
---@field SetDataRaw fun(self: df_data, data: table) set the data without triggering callback
|
|
---@field GetDataNextValue fun(self: df_data) : any
|
|
---@field ResetDataIndex fun(self: df_data)
|
|
|
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.DataMixin)
|
|
---add 'data' to a table, this table can be used to store data for the object
|
|
---@class DetailsFramework.DataMixin
|
|
detailsFramework.DataMixin = {
|
|
---initialize the data table
|
|
---@param self table
|
|
DataConstructor = function(self)
|
|
self._dataInfo = {
|
|
data = {},
|
|
dataCurrentIndex = 1,
|
|
callbacks = {},
|
|
}
|
|
end,
|
|
|
|
---when data is changed, functions registered with this function will be called
|
|
---@param self table
|
|
---@param func function
|
|
---@param ... unknown
|
|
AddDataChangeCallback = function(self, func, ...)
|
|
assert(type(func) == "function", "invalid function for AddDataChangeCallback.")
|
|
local allCallbacks = self._dataInfo.callbacks
|
|
allCallbacks[func] = {...}
|
|
end,
|
|
|
|
---remove a previous registered callback function
|
|
---@param self table
|
|
---@param func function
|
|
RemoveDataChangeCallback = function(self, func)
|
|
assert(type(func) == "function", "invalid function for RemoveDataChangeCallback.")
|
|
local allCallbacks = self._dataInfo.callbacks
|
|
allCallbacks[func] = nil
|
|
end,
|
|
|
|
---set the data without callback
|
|
---@param self table
|
|
---@param data table
|
|
SetDataRaw = function(self, data)
|
|
assert(type(data) == "table", "invalid table for SetData.")
|
|
self._dataInfo.data = data
|
|
self:ResetDataIndex()
|
|
end,
|
|
|
|
---set the data table
|
|
---@param self table
|
|
---@param data table
|
|
---@param anyValue any @any value to pass to the callback functions before the payload is added
|
|
SetData = function(self, data, anyValue)
|
|
assert(type(data) == "table", "invalid table for SetData.")
|
|
self._dataInfo.data = data
|
|
self:ResetDataIndex()
|
|
|
|
local allCallbacks = self._dataInfo.callbacks
|
|
for func, payload in pairs(allCallbacks) do
|
|
xpcall(func, geterrorhandler(), data, anyValue, unpack(payload))
|
|
end
|
|
end,
|
|
|
|
---get the data table
|
|
---@param self table
|
|
GetData = function(self)
|
|
return self._dataInfo.data
|
|
end,
|
|
|
|
---get the next value from the data table
|
|
---@param self table
|
|
---@return any
|
|
GetDataNextValue = function(self)
|
|
local currentValue = self._dataInfo.dataCurrentIndex
|
|
local value = self:GetData()[currentValue]
|
|
self._dataInfo.dataCurrentIndex = self._dataInfo.dataCurrentIndex + 1
|
|
return value
|
|
end,
|
|
|
|
---reset the data index, making GetDataNextValue() return the first value again
|
|
---@param self table
|
|
ResetDataIndex = function(self)
|
|
self._dataInfo.dataCurrentIndex = 1
|
|
end,
|
|
|
|
---get the size of the data table
|
|
---@param self table
|
|
---@return number
|
|
GetDataSize = function(self)
|
|
return #self:GetData()
|
|
end,
|
|
|
|
---get the first value from the data table
|
|
---@param self table
|
|
---@return any
|
|
GetDataFirstValue = function(self)
|
|
return self:GetData()[1]
|
|
end,
|
|
|
|
---get the last value from the data table
|
|
---@param self table
|
|
---@return any
|
|
GetDataLastValue = function(self)
|
|
local data = self:GetData()
|
|
return data[#data]
|
|
end,
|
|
|
|
---get the min and max values from the data table, if the value stored is number, return the min and max values
|
|
---could be used together with SetMinMaxValues from the df_value mixin
|
|
---@param self table
|
|
---@return number, number
|
|
GetDataMinMaxValues = function(self)
|
|
local minDataValue = 0
|
|
local maxDataValue = 0
|
|
|
|
local data = self:GetData()
|
|
for i = 1, #data do
|
|
local thisData = data[i]
|
|
if (thisData > maxDataValue) then
|
|
maxDataValue = thisData
|
|
|
|
elseif (thisData < minDataValue) then
|
|
minDataValue = thisData
|
|
end
|
|
end
|
|
|
|
return minDataValue, maxDataValue
|
|
end,
|
|
|
|
---when data uses sub tables, get the min max values from a specific index or key, if the value stored is number, return the min and max values
|
|
---@param self table
|
|
---@param key string
|
|
---@return number, number
|
|
GetDataMinMaxValueFromSubTable = function(self, key)
|
|
local minDataValue = 0
|
|
local maxDataValue = 0
|
|
|
|
local data = self:GetData()
|
|
for i = 1, #data do
|
|
local thisData = data[i]
|
|
if (thisData[key] > maxDataValue) then
|
|
maxDataValue = thisData[key]
|
|
|
|
elseif (thisData[key] < minDataValue) then
|
|
minDataValue = thisData[key]
|
|
end
|
|
end
|
|
|
|
return minDataValue, maxDataValue
|
|
end,
|
|
}
|
|
|
|
---@class df_value : table
|
|
---@field minValue number
|
|
---@field maxValue number
|
|
---@field ValueConstructor fun(self: df_value)
|
|
---@field SetMinMaxValues fun(self: df_value, minValue: number, maxValue: number)
|
|
---@field GetMinMaxValues fun(self: df_value) : number, number
|
|
---@field ResetMinMaxValues fun(self: df_value)
|
|
---@field GetMinValue fun(self: df_value) : number
|
|
---@field GetMaxValue fun(self: df_value) : number
|
|
---@field SetMinValue fun(self: df_value, minValue: number)
|
|
---@field SetMinValueIfLower fun(self: df_value, ...: number)
|
|
---@field SetMaxValue fun(self: df_value, maxValue: number)
|
|
---@field SetMaxValueIfBigger fun(self: df_value, ...: number)
|
|
|
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.ValueMixin)
|
|
---add support to min value and max value into a table or object
|
|
---@class DetailsFramework.ValueMixin
|
|
detailsFramework.ValueMixin = {
|
|
---initialize the value table
|
|
---@param self table
|
|
ValueConstructor = function(self)
|
|
self:ResetMinMaxValues()
|
|
end,
|
|
|
|
---set the min and max values
|
|
---@param self table
|
|
---@param minValue number
|
|
---@param maxValue number
|
|
SetMinMaxValues = function(self, minValue, maxValue)
|
|
self.minValue = minValue
|
|
self.maxValue = maxValue
|
|
end,
|
|
|
|
---get the min and max values
|
|
---@param self table
|
|
---@return number, number
|
|
GetMinMaxValues = function(self)
|
|
return self.minValue, self.maxValue
|
|
end,
|
|
|
|
---reset the min and max values
|
|
---@param self table
|
|
ResetMinMaxValues = function(self)
|
|
self.minValue = 0
|
|
self.maxValue = 1
|
|
end,
|
|
|
|
---get the min value
|
|
---@param self table
|
|
---@return number
|
|
GetMinValue = function(self)
|
|
return self.minValue
|
|
end,
|
|
|
|
---get the max value
|
|
---@param self table
|
|
---@return number
|
|
GetMaxValue = function(self)
|
|
return self.maxValue
|
|
end,
|
|
|
|
---set the min value
|
|
---@param self table
|
|
---@param minValue number
|
|
SetMinValue = function(self, minValue)
|
|
self.minValue = minValue
|
|
end,
|
|
|
|
---set the min value if one of the values passed is lower than the current min value
|
|
---@param self table
|
|
---@param ... number
|
|
SetMinValueIfLower = function(self, ...)
|
|
self.minValue = math.min(self.minValue, ...)
|
|
end,
|
|
|
|
---set the max value
|
|
---@param self table
|
|
---@param maxValue number
|
|
SetMaxValue = function(self, maxValue)
|
|
self.maxValue = maxValue
|
|
end,
|
|
|
|
---set the max value if one of the values passed is bigger than the current max value
|
|
---@param self table
|
|
---@param ... number
|
|
SetMaxValueIfBigger = function(self, ...)
|
|
self.maxValue = math.max(self.maxValue, ...)
|
|
end,
|
|
}
|
|
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--statusbar mixin
|
|
|
|
--[=[
|
|
collection of functions to embed into a statusbar
|
|
the statusBar need to have a member called 'barTexture' for the texture set on SetStatusBarTexture
|
|
statusBar:GetTexture()
|
|
statusBar:SetTexture(texture)
|
|
statusBar:SetColor (unparsed color)
|
|
statusBar:GetColor()
|
|
statusBar:
|
|
statusBar:
|
|
--]=]
|
|
|
|
---@class df_statusbarmixin : table
|
|
---@field SetTexture fun(self: table, texture: string, isTemporary: boolean)
|
|
---@field ResetTexture fun(self: table)
|
|
---@field GetTexture fun(self: table) : string
|
|
---@field SetAtlas fun(self: table, atlasName: string)
|
|
---@field GetAtlas fun(self: table) : string
|
|
---@field SetTexCoord fun(self: table, ...)
|
|
---@field GetTexCoord fun(self: table) : number, number, number, number
|
|
---@field SetColor fun(self: table, ...)
|
|
---@field GetColor fun(self: table) : number, number, number, number
|
|
---@field SetMaskTexture fun(self: table, texture: string)
|
|
---@field GetMaskTexture fun(self: table) : string
|
|
---@field SetMaskTexCoord fun(self: table, ...)
|
|
---@field GetMaskTexCoord fun(self: table) : number, number, number, number
|
|
---@field SetMaskAtlas fun(self: table, atlasName: string)
|
|
---@field GetMaskAtlas fun(self: table) : string
|
|
---@field AddMaskTexture fun(self: table, texture: string)
|
|
---@field SetBorderTexture fun(self: table, texture: string)
|
|
---@field GetBorderTexture fun(self: table) : string
|
|
---@field SetBorderColor fun(self: table, ...)
|
|
---@field GetBorderColor fun(self: table) : number, number, number, number
|
|
---@field SetDesaturated fun(self: table, bIsDesaturated: boolean)
|
|
---@field IsDesaturated fun(self: table) : boolean
|
|
---@field SetVertexColor fun(self: table, red: any, green: number?, blue: number?, alpha: number?)
|
|
---@field GetVertexColor fun(self: table) : number, number, number, number
|
|
|
|
detailsFramework.StatusBarFunctions = {
|
|
SetTexture = function(self, texture, isTemporary)
|
|
self.barTexture:SetTexture(texture)
|
|
if (not isTemporary) then
|
|
self.barTexture.currentTexture = texture
|
|
end
|
|
end,
|
|
|
|
ResetTexture = function(self)
|
|
self.barTexture:SetTexture(self.barTexture.currentTexture)
|
|
end,
|
|
|
|
GetTexture = function(self)
|
|
return self.barTexture:GetTexture()
|
|
end,
|
|
|
|
SetDesaturated = function(self, bIsDesaturated)
|
|
self.barTexture:SetDesaturated(bIsDesaturated)
|
|
end,
|
|
|
|
SetDesaturation = function(self, desaturationAmount)
|
|
self.barTexture:SetDesaturation(desaturationAmount)
|
|
end,
|
|
|
|
IsDesaturated = function(self)
|
|
return self.barTexture:IsDesaturated()
|
|
end,
|
|
|
|
SetVertexColor = function(self, red, green, blue, alpha)
|
|
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
|
self.barTexture:SetVertexColor(red, green, blue, alpha)
|
|
end,
|
|
|
|
GetVertexColor = function(self)
|
|
return self.barTexture:GetVertexColor()
|
|
end,
|
|
|
|
SetAtlas = function(self, atlasName)
|
|
self.barTexture:SetAtlas(atlasName)
|
|
end,
|
|
|
|
GetAtlas = function(self)
|
|
self.barTexture:GetAtlas()
|
|
end,
|
|
|
|
SetTexCoord = function(self, ...)
|
|
local left, right, top, bottom = ...
|
|
return self.barTexture:SetTexCoord(...)
|
|
end,
|
|
|
|
GetTexCoord = function(self)
|
|
return self.barTexture:GetTexCoord()
|
|
end,
|
|
|
|
SetColor = function(self, r, g, b, a)
|
|
r, g, b, a = detailsFramework:ParseColors(r, g, b, a)
|
|
self:SetStatusBarColor(r, g, b, a)
|
|
end,
|
|
|
|
GetColor = function(self)
|
|
return self:GetStatusBarColor()
|
|
end,
|
|
|
|
SetMaskTexture = function(self, ...)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
self.barTextureMask:SetTexture(...)
|
|
end,
|
|
|
|
GetMaskTexture = function(self)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
self.barTextureMask:GetTexture()
|
|
end,
|
|
|
|
SetMaskAtlas = function(self, atlasName)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
self.barTextureMask:SetAtlas(atlasName)
|
|
end,
|
|
|
|
GetMaskAtlas = function(self)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
self.barTextureMask:GetAtlas()
|
|
end,
|
|
|
|
AddMaskTexture = function(self, object)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
if (object.GetObjectType and object:GetObjectType() == "Texture") then
|
|
object:AddMaskTexture(self.barTextureMask)
|
|
else
|
|
detailsFramework:Msg("Invalid 'Texture' to object:AddMaskTexture(Texture)", debugstack())
|
|
end
|
|
end,
|
|
|
|
CreateTextureMask = function(self)
|
|
local barTexture = self:GetStatusBarTexture() or self.barTexture
|
|
if (not barTexture) then
|
|
detailsFramework:Msg("Object doesn't not have a statubar texture, create one and object:SetStatusBarTexture(textureObject)", debugstack())
|
|
return
|
|
end
|
|
|
|
if (self.barTextureMask) then
|
|
return self.barTextureMask
|
|
end
|
|
|
|
--statusbar texture mask
|
|
self.barTextureMask = self:CreateMaskTexture(nil, "artwork")
|
|
self.barTextureMask:SetAllPoints()
|
|
self.barTextureMask:SetTexture([[Interface\CHATFRAME\CHATFRAMEBACKGROUND]])
|
|
|
|
--border texture
|
|
self.barBorderTextureForMask = self:CreateTexture(nil, "overlay", nil, 7)
|
|
self.barBorderTextureForMask:SetAllPoints()
|
|
--self.barBorderTextureForMask:SetPoint("topleft", self, "topleft", -1, 1)
|
|
--self.barBorderTextureForMask:SetPoint("bottomright", self, "bottomright", 1, -1)
|
|
self.barBorderTextureForMask:Hide()
|
|
|
|
barTexture:AddMaskTexture(self.barTextureMask)
|
|
|
|
return self.barTextureMask
|
|
end,
|
|
|
|
HasTextureMask = function(self)
|
|
if (not self.barTextureMask) then
|
|
detailsFramework:Msg("Object doesn't not have a texture mask, create one using object:CreateTextureMask()", debugstack())
|
|
return false
|
|
end
|
|
return true
|
|
end,
|
|
|
|
SetBorderTexture = function(self, texture)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
|
|
texture = texture or ""
|
|
|
|
self.barBorderTextureForMask:SetTexture(texture)
|
|
|
|
if (texture == "") then
|
|
self.barBorderTextureForMask:Hide()
|
|
else
|
|
self.barBorderTextureForMask:Show()
|
|
end
|
|
end,
|
|
|
|
GetBorderTexture = function(self)
|
|
if (not self:HasTextureMask()) then
|
|
return
|
|
end
|
|
return self.barBorderTextureForMask:GetTexture()
|
|
end,
|
|
|
|
SetBorderColor = function(self, r, g, b, a)
|
|
r, g, b, a = detailsFramework:ParseColors(r, g, b, a)
|
|
|
|
if (self.barBorderTextureForMask and self.barBorderTextureForMask:IsShown()) then
|
|
self.barBorderTextureForMask:SetVertexColor(r, g, b, a)
|
|
|
|
--if there's a square border on the widget, remove its color
|
|
if (self.border and self.border.UpdateSizes and self.border.SetVertexColor) then
|
|
self.border:SetVertexColor(0, 0, 0, 0)
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
if (self.border and self.border.UpdateSizes and self.border.SetVertexColor) then
|
|
self.border:SetVertexColor(r, g, b, a)
|
|
|
|
--adjust the mask border texture ask well in case the user set the mask color texture before setting a texture on it
|
|
if (self.barBorderTextureForMask) then
|
|
self.barBorderTextureForMask:SetVertexColor(r, g, b, a)
|
|
end
|
|
return
|
|
end
|
|
end,
|
|
|
|
GetBorderColor = function(self)
|
|
if (self.barBorderTextureForMask and self.barBorderTextureForMask:IsShown()) then
|
|
return self.barBorderTextureForMask:GetVertexColor()
|
|
end
|
|
|
|
if (self.border and self.border.UpdateSizes and self.border.GetVertexColor) then
|
|
return self.border:GetVertexColor()
|
|
end
|
|
end,
|
|
}
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--frame mixin
|
|
local createTexture = CreateFrame('Frame').CreateTexture -- need a local "original" CreateFrame
|
|
|
|
detailsFramework.FrameFunctions = {
|
|
CreateTexture = function(self, name, drawLayer, templateName, subLevel)
|
|
local texture = createTexture(self, name, drawLayer, templateName, subLevel)
|
|
-- pixel perfection
|
|
texture:SetTexelSnappingBias(0)
|
|
texture:SetSnapToPixelGrid(false)
|
|
return texture
|
|
end,
|
|
}
|
|
|