Open Raid Library update
This commit is contained in:
+1
-1
@@ -813,7 +813,7 @@ function DF:CreateAuraConfigPanel (parent, name, db, change_callback, options, t
|
||||
icon:SetSize(lineHeight - 2, lineHeight - 2)
|
||||
|
||||
local name = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||||
DF:SetFontSize (name, 10)
|
||||
DF:SetFontSize(name, 10)
|
||||
|
||||
local remove_button = CreateFrame("button", "$parentRemoveButton", line, "UIPanelCloseButton")
|
||||
remove_button:SetSize(16, 16)
|
||||
|
||||
+1
-1
@@ -205,7 +205,7 @@ DF:Mixin(ButtonMetaFunctions, DF.ScriptHookMixin)
|
||||
|
||||
--text size
|
||||
local smember_textsize = function(object, value)
|
||||
return DF:SetFontSize (object.button.text, value)
|
||||
return DF:SetFontSize(object.button.text, value)
|
||||
end
|
||||
|
||||
--texture
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
|
||||
local ChartFrameMixin = {
|
||||
ChartFrameConstructor = function(self)
|
||||
self.nextLine = 1
|
||||
self.minValue = 0
|
||||
self.maxValue = 1
|
||||
self.lineThickness = 1
|
||||
self.data = {}
|
||||
self.lines = {}
|
||||
|
||||
--OnSizeChanged
|
||||
self:SetScript("OnSizeChanged", self.OnSizeChanged)
|
||||
end,
|
||||
|
||||
--internally handle next line
|
||||
GetLine = function(self)
|
||||
local line = self.lines[self.nextLine]
|
||||
if (not line) then
|
||||
line = self:CreateLine(nil, "overlay")
|
||||
self.lines[self.nextLine] = line
|
||||
end
|
||||
self.nextLine = self.nextLine + 1
|
||||
line:Show()
|
||||
return line
|
||||
end,
|
||||
|
||||
GetLines = function(self)
|
||||
return self.lines
|
||||
end,
|
||||
|
||||
GetAmountLines = function(self)
|
||||
return self.nextLine - 1
|
||||
end,
|
||||
|
||||
HideLines = function(self)
|
||||
local allLines = self:GetLines()
|
||||
for i = 1, #allLines do
|
||||
local line = allLines[i]
|
||||
line:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self:HideLines()
|
||||
self.nextLine = 1
|
||||
end,
|
||||
|
||||
SetLineThickness = function(self, value)
|
||||
assert(type(value) == "number", "number expected on :SetLineThickness(number)")
|
||||
self.lineThickness = value
|
||||
end,
|
||||
|
||||
--calculate the width of each drawn line
|
||||
GetLineWidth = function(self)
|
||||
--self:SetLineWidth(nil) to erase the fixed value
|
||||
if (self.fixedLineWidth) then
|
||||
return self.fixedLineWidth
|
||||
else
|
||||
local amountData = self:GetDataSize()
|
||||
local frameWidth = self:GetWidth()
|
||||
return frameWidth / amountData
|
||||
end
|
||||
end,
|
||||
|
||||
SetLineWidth = function(self, width)
|
||||
assert(type(width) == "number", "number expected on :SetLineWidth(number)")
|
||||
self.fixedLineWidth = width
|
||||
end,
|
||||
|
||||
CalcYAxisPointForValue = function(self, value)
|
||||
return value / self.maxValue * self.height
|
||||
end,
|
||||
|
||||
UpdateFrameSizeCache = function(self)
|
||||
self.width = self:GetWidth()
|
||||
self.height = self:GetHeight()
|
||||
end,
|
||||
|
||||
OnSizeChanged = function(self)
|
||||
self:UpdateFrameSizeCache()
|
||||
end,
|
||||
|
||||
Plot = function(self)
|
||||
--debug
|
||||
--self:SetData({38, 26, 12, 63, 100, 96, 42, 94, 25, 75, 61, 54, 71, 40, 34, 100, 66, 90, 39, 13, 99, 18, 72, 18, 83, 45, 56, 24, 33, 85, 95, 71, 15, 66, 19, 58, 52, 9, 83, 99, 100, 4, 3, 56, 6, 80, 94, 7, 40, 55, 98, 92, 20, 9, 35, 89, 72, 7, 13, 81, 29, 78, 55, 70, 12, 33, 39, 3, 84, 31, 10, 53, 51, 69, 66, 58, 71, 60, 31, 71, 27, 76, 21, 75, 15, 89, 2, 81, 72, 78, 74, 80, 97, 10, 59, 0, 31, 5, 1, 82, 71, 89, 78, 94, 74, 20, 65, 72, 56, 40, 92, 91, 40, 79, 4, 56, 18, 88, 88, 20, 20, 10, 47, 26, 80, 26, 75, 21, 57, 10, 67, 66, 84, 83, 14, 47, 83, 9, 7, 73, 63, 32, 64, 20, 40, 3, 46, 54, 17, 37, 82, 66, 65, 22, 12, 1, 100, 41, 1, 72, 38, 41, 71, 69, 88, 34, 10, 50, 9, 25, 19, 27, 3, 13, 40, 75, 3, 11, 93, 58, 81, 80, 93, 25, 74, 68, 91, 87, 79, 48, 66, 53, 64, 18, 51, 19, 32, 4, 21, 43})
|
||||
local currentXPoint = 0
|
||||
local currentYPoint = 0
|
||||
|
||||
self:UpdateFrameSizeCache()
|
||||
|
||||
--max amount of data is the max amount of point the chart will have
|
||||
local maxLines = self:GetDataSize()
|
||||
|
||||
--calculate where the first point height will be
|
||||
local firstValue = self:GetDataFirstValue()
|
||||
assert(firstValue, "Can't Plot(), chart has no data, use Chart:SetData(table)")
|
||||
|
||||
currentYPoint = self:CalcYAxisPointForValue(firstValue)
|
||||
|
||||
--calculate the width space which line should have
|
||||
local eachLineWidth = self:GetLineWidth()
|
||||
|
||||
self:ResetDataIndex()
|
||||
|
||||
for i = 1, maxLines do
|
||||
local line = self:GetLine()
|
||||
line:SetColorTexture(1, 1, 1, 1)
|
||||
line:SetThickness(1)
|
||||
|
||||
--the start point starts where the latest point finished
|
||||
line:SetStartPoint("bottomleft", currentXPoint, currentYPoint)
|
||||
|
||||
--move x
|
||||
currentXPoint = currentXPoint + eachLineWidth
|
||||
|
||||
--end point
|
||||
local value = self:GetDataNextValue()
|
||||
currentYPoint = self:CalcYAxisPointForValue(value)
|
||||
line:SetEndPoint("bottomleft", currentXPoint, currentYPoint)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
local createChartFrame = function(parent, name)
|
||||
local f = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
|
||||
DF:Mixin(f, DF.DataMixin)
|
||||
DF:Mixin(f, DF.ValueMixin)
|
||||
DF:Mixin(f, ChartFrameMixin)
|
||||
|
||||
f:DataConstructor()
|
||||
f:ValueConstructor()
|
||||
f:ChartFrameConstructor()
|
||||
|
||||
--when a new data is set, update the min and max values
|
||||
local onSetDataCallback = function()
|
||||
local minValue, maxValue = f:GetDataMinMaxValues()
|
||||
f:SetMinMaxValues(minValue, maxValue)
|
||||
--clear the lines
|
||||
f:HideLines()
|
||||
end
|
||||
f:AddDataChangeCallback(onSetDataCallback)
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
function DF:CreateGraphicLineFrame(parent, name)
|
||||
local newGraphicFrame = createChartFrame(parent, name)
|
||||
return newGraphicFrame
|
||||
end
|
||||
|
||||
local MultiChartFrameMixin = {
|
||||
MultiChartFrameConstructor = function(self)
|
||||
self.nextChartselframe = 1
|
||||
self.biggestDataValue = 0
|
||||
self.chartFrames = {}
|
||||
end,
|
||||
|
||||
AddData = function(self, data)
|
||||
assert(type(data) == "table", "MultiChartFrame:AddData() usage: AddData(table)")
|
||||
local chartFrame = self:GetChart()
|
||||
chartFrame:SetData(data)
|
||||
|
||||
self:SetMaxValueIfBigger(chartFrame:GetMaxValue())
|
||||
self:SetMinValueIfLower(chartFrame:GetMinValue())
|
||||
|
||||
local dataAmount = chartFrame:GetDataSize()
|
||||
self:SetMaxDataSize(dataAmount)
|
||||
end,
|
||||
|
||||
--internally handle next line
|
||||
GetChart = function(self)
|
||||
local chartFrame = self.chartFrames[self.nextChartFrame]
|
||||
if (not chartFrame) then
|
||||
chartFrame = createChartFrame(self, "$parentChartFrame" .. self.nextChartFrame)
|
||||
chartFrame:SetAllPoints()
|
||||
chartFrame:UpdateFrameSizeCache()
|
||||
self.chartFrames[self.nextChartFrame] = chartFrame
|
||||
end
|
||||
self.nextChartFrame = self.nextChartFrame + 1
|
||||
chartFrame:Show()
|
||||
return chartFrame
|
||||
end,
|
||||
|
||||
GetCharts = function(self)
|
||||
return self.chartFrames
|
||||
end,
|
||||
|
||||
GetAmountCharts = function(self)
|
||||
return self.nextChartFrame - 1
|
||||
end,
|
||||
|
||||
HideCharts = function(self)
|
||||
local charts = self:GetCharts()
|
||||
for i = 1, #charts do
|
||||
local chartFrame = charts[i]
|
||||
chartFrame:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self:HideCharts()
|
||||
self.nextChartFrame = 1
|
||||
end,
|
||||
|
||||
SetChartsMinMaxValues = function(self, minValue, maxValue)
|
||||
local allCharts = self:GetCharts()
|
||||
for i = 1, self:GetAmountCharts() do
|
||||
local chartFrame = allCharts[i]
|
||||
chartFrame:SetMinMaxValues(minValue, maxValue)
|
||||
end
|
||||
end,
|
||||
|
||||
SetMaxDataSize = function(self, dataSize)
|
||||
self.biggestDataValue = max(self.biggestDataValue, dataSize)
|
||||
end,
|
||||
|
||||
GetMaxDataSize = function(self)
|
||||
return self.biggestDataValue
|
||||
end,
|
||||
|
||||
Plot = function(self)
|
||||
local minValue, maxValue = self:GetMinMaxValues()
|
||||
self:SetChartsMinMaxValues(minValue, maxValue)
|
||||
|
||||
local plotAreaWidth = self:GetWidth()
|
||||
local maxDataSize = self:GetMaxDataSize()
|
||||
local eachLineWidth = plotAreaWidth / maxDataSize
|
||||
|
||||
local allCharts = self:GetCharts()
|
||||
for i = 1, self:GetAmountCharts() do
|
||||
local chartFrame = allCharts[i]
|
||||
chartFrame:SetLineWidth(eachLineWidth)
|
||||
chartFrame:Plot()
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
function DF:CreateGraphicMultiLineFrame(parent, name)
|
||||
name = name or ("DetailsMultiChartFrameID" .. math.random(1, 10000000))
|
||||
|
||||
local f = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
|
||||
DF:Mixin(f, DF.ValueMixin)
|
||||
DF:Mixin(f, MultiChartFrameMixin)
|
||||
|
||||
f:ValueConstructor()
|
||||
f:MultiChartFrameConstructor()
|
||||
|
||||
return f
|
||||
end
|
||||
+26
-1
@@ -15,7 +15,7 @@ local max = math.max
|
||||
|
||||
--api locals
|
||||
local PixelUtil = PixelUtil or DFPixelUtil
|
||||
local version = 5
|
||||
local version = 6
|
||||
|
||||
local CONST_MENU_TYPE_MAINMENU = "main"
|
||||
local CONST_MENU_TYPE_SUBMENU = "sub"
|
||||
@@ -3207,6 +3207,31 @@ function DF:CreateCoolTip()
|
||||
gameCooltip:Hide()
|
||||
end)
|
||||
end
|
||||
|
||||
local cyrillic = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯЁЂЃЄЅІЇЈЉЊЋЌЎЏҐабвгдежзийклмнопрстуфхцчшщъыьэюяёђѓєѕіїјљњћќўџґАаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя"
|
||||
local latin = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local chinese = "ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ"
|
||||
|
||||
local alphabetTable = {}
|
||||
|
||||
for letter in latin:gmatch(".") do
|
||||
alphabetTable[letter] = "enUS"
|
||||
end
|
||||
for letter in cyrillic:gmatch(".") do
|
||||
alphabetTable[letter] = "ruRU"
|
||||
end
|
||||
for letter in chinese:gmatch(".") do
|
||||
alphabetTable[letter] = "zhCN"
|
||||
end
|
||||
|
||||
function gameCooltip:DetectLanguageId(text)
|
||||
for letter in text:gmatch(".") do
|
||||
if (alphabetTable[letter]) then
|
||||
return alphabetTable[letter]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return gameCooltip
|
||||
end
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
local dversion = 381
|
||||
local dversion = 382
|
||||
local major, minor = "DetailsFramework-1.0", dversion
|
||||
local DF, oldminor = LibStub:NewLibrary(major, minor)
|
||||
|
||||
@@ -3384,7 +3384,7 @@ end
|
||||
|
||||
--this is most copied from the wow client code, few changes applied to customize it
|
||||
function DF:CreateGlowOverlay (parent, antsColor, glowColor)
|
||||
local glowFrame = CreateFrame("frame", parent:GetName() and "$parentGlow2" or "OverlayActionGlow" .. math.random (1, 10000000), parent, "ActionBarButtonSpellActivationAlert")
|
||||
local glowFrame = CreateFrame("frame", parent:GetName() and "$parentGlow2" or "OverlayActionGlow" .. math.random(1, 10000000), parent, "ActionBarButtonSpellActivationAlert")
|
||||
glowFrame:HookScript ("OnShow", glow_overlay_onshow)
|
||||
glowFrame:HookScript ("OnHide", glow_overlay_onhide)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<Script file="savedvars.lua"/>
|
||||
<Script file="languages.lua"/>
|
||||
<Script file="timebar.lua"/>
|
||||
<Script file="charts.lua"/>
|
||||
|
||||
<Include file="tutorial_alert.xml"/>
|
||||
<Include file="split_bar.xml"/>
|
||||
|
||||
@@ -685,4 +685,143 @@ detailsFramework.SortFunctions = {
|
||||
table.sort(thisTable, SortByMemberReverse)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
detailsFramework.DataMixin = {
|
||||
DataConstructor = function(self)
|
||||
self._dataInfo = {
|
||||
data = {},
|
||||
dataCurrentIndex = 1,
|
||||
callbacks = {},
|
||||
}
|
||||
end,
|
||||
|
||||
AddDataChangeCallback = function(self, func, ...)
|
||||
assert(type(func) == "function", "invalid function for AddDataChangeCallback.")
|
||||
local allCallbacks = self._dataInfo.callbacks
|
||||
allCallbacks[func] = {...}
|
||||
end,
|
||||
|
||||
RemoveDataChangeCallback = function(self, func)
|
||||
assert(type(func) == "function", "invalid function for RemoveDataChangeCallback.")
|
||||
local allCallbacks = self._dataInfo.callbacks
|
||||
allCallbacks[func] = nil
|
||||
end,
|
||||
|
||||
SetData = function(self, data)
|
||||
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, unpack(payload))
|
||||
end
|
||||
end,
|
||||
|
||||
GetData = function(self)
|
||||
return self._dataInfo.data
|
||||
end,
|
||||
|
||||
GetDataNextValue = function(self)
|
||||
local currentValue = self._dataInfo.dataCurrentIndex
|
||||
local value = self:GetData()[currentValue]
|
||||
self._dataInfo.dataCurrentIndex = self._dataInfo.dataCurrentIndex + 1
|
||||
return value
|
||||
end,
|
||||
|
||||
ResetDataIndex = function(self)
|
||||
self._dataInfo.dataCurrentIndex = 1
|
||||
end,
|
||||
|
||||
GetDataSize = function(self)
|
||||
return #self:GetData()
|
||||
end,
|
||||
|
||||
GetDataFirstValue = function(self)
|
||||
return self:GetData()[1]
|
||||
end,
|
||||
|
||||
GetDataLastValue = function(self)
|
||||
local data = self:GetData()
|
||||
return data[#data]
|
||||
end,
|
||||
|
||||
--if the value stored is number, return the min and max values
|
||||
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
|
||||
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,
|
||||
}
|
||||
|
||||
detailsFramework.ValueMixin = {
|
||||
ValueConstructor = function(self)
|
||||
self.minValue = 0
|
||||
self.maxValue = 1
|
||||
end,
|
||||
|
||||
SetMinMaxValues = function(self, minValue, maxValue)
|
||||
self.minValue = minValue
|
||||
self.maxValue = maxValue
|
||||
end,
|
||||
|
||||
GetMinMaxValues = function(self)
|
||||
return self.minValue, self.maxValue
|
||||
end,
|
||||
|
||||
GetMinValue = function(self)
|
||||
return self.minValue
|
||||
end,
|
||||
|
||||
GetMaxValue = function(self)
|
||||
return self.maxValue
|
||||
end,
|
||||
|
||||
SetMinValue = function(self, minValue)
|
||||
self.minValue = minValue
|
||||
end,
|
||||
|
||||
SetMinValueIfLower = function(self, ...)
|
||||
self.minValue = min(self.minValue, ...)
|
||||
end,
|
||||
|
||||
SetMaxValue = function(self, maxValue)
|
||||
self.maxValue = maxValue
|
||||
end,
|
||||
|
||||
SetMaxValueIfBigger = function(self, ...)
|
||||
self.maxValue = max(self.maxValue, ...)
|
||||
end,
|
||||
}
|
||||
@@ -302,8 +302,8 @@ DF:Mixin(BarMetaFunctions, DF.ScriptHookMixin)
|
||||
end
|
||||
--font size
|
||||
local smember_textsize = function(_object, _value)
|
||||
DF:SetFontSize (_object.textleft, _value)
|
||||
return DF:SetFontSize (_object.textright, _value)
|
||||
DF:SetFontSize(_object.textleft, _value)
|
||||
return DF:SetFontSize(_object.textright, _value)
|
||||
end
|
||||
--font color
|
||||
local smember_textcolor = function(_object, _value)
|
||||
@@ -613,7 +613,7 @@ DF:Mixin(BarMetaFunctions, DF.ScriptHookMixin)
|
||||
--right text
|
||||
self.remaining = self.remaining - elapsed
|
||||
if (self.MyObject.RightTextIsTimer) then
|
||||
self.righttext:SetText(DF:IntegerToTimer (self.remaining))
|
||||
self.righttext:SetText(DF:IntegerToTimer(self.remaining))
|
||||
else
|
||||
self.righttext:SetText(_math_floor(self.remaining))
|
||||
end
|
||||
@@ -739,11 +739,11 @@ local build_statusbar = function(self)
|
||||
self.lefttext = self:CreateFontString("$parent_TextLeft", "OVERLAY", "GameFontHighlight")
|
||||
self.lefttext:SetJustifyH("LEFT")
|
||||
self.lefttext:SetPoint("LEFT", self.icontexture, "RIGHT", 3, 0)
|
||||
DF:SetFontSize (self.lefttext, 10)
|
||||
DF:SetFontSize(self.lefttext, 10)
|
||||
|
||||
self.righttext = self:CreateFontString("$parent_TextRight", "OVERLAY", "GameFontHighlight")
|
||||
self.righttext:SetJustifyH("LEFT")
|
||||
DF:SetFontSize (self.righttext, 10)
|
||||
DF:SetFontSize(self.righttext, 10)
|
||||
self.righttext:SetPoint("RIGHT", self, "RIGHT", -3, 0)
|
||||
|
||||
DetailsFrameworkNormalBar_OnCreate (self)
|
||||
|
||||
+154
-167
@@ -783,7 +783,7 @@ local align_rows = function(self)
|
||||
text:SetPoint("left", line, "left", self._anchors [#self._anchors], 0)
|
||||
text:SetWidth(row.width)
|
||||
|
||||
detailsFramework:SetFontSize (text, row.textsize or 10)
|
||||
detailsFramework:SetFontSize(text, row.textsize or 10)
|
||||
text:SetJustifyH(row.textalign or "left")
|
||||
end
|
||||
elseif (rowType == "entry") then
|
||||
@@ -953,7 +953,7 @@ local update_rows = function(self, updated_rows)
|
||||
--
|
||||
|
||||
widget.text:SetText(t.name)
|
||||
detailsFramework:SetFontSize (widget.text, raw.textsize or 10)
|
||||
detailsFramework:SetFontSize(widget.text, raw.textsize or 10)
|
||||
widget.text:SetJustifyH(raw.textalign or "left")
|
||||
end
|
||||
end
|
||||
@@ -2874,82 +2874,80 @@ local chart_panel_onresize = function(self)
|
||||
self.Graphic:SetPoint("topleft", self, "topleft", 108, -35)
|
||||
end
|
||||
|
||||
local chart_panel_add_data = function(self, graphicData, color, name, elapsed_time, lineTexture, smoothLevel, firstIndex)
|
||||
local f = self
|
||||
self = self.Graphic
|
||||
|
||||
local _data = {}
|
||||
local max_value = graphicData.max_value
|
||||
local amount = #graphicData
|
||||
|
||||
local scaleW = 1/self:GetWidth()
|
||||
local chart_panel_add_data = function(self, graphicData, color, name, elapsedTime, lineTexture, smoothLevel, firstIndex)
|
||||
local chartPanel = self --chartPanel from the framework CreateChartPanel
|
||||
local LibGraphChartFrame = self.Graphic
|
||||
|
||||
local builtData = {}
|
||||
local maxValue = graphicData.max_value
|
||||
local scaleWidth = 1 / LibGraphChartFrame:GetWidth()
|
||||
local content = graphicData
|
||||
|
||||
--smooth the start and end of the chart
|
||||
tinsert(content, 1, 0)
|
||||
tinsert(content, 1, 0)
|
||||
tinsert(content, #content+1, 0)
|
||||
tinsert(content, #content+1, 0)
|
||||
|
||||
local _i = 3
|
||||
|
||||
local graphMaxDps = math.max(self.max_value, max_value)
|
||||
local index = 3
|
||||
local graphMaxDps = math.max(LibGraphChartFrame.max_value, maxValue)
|
||||
|
||||
--do smoothness progress
|
||||
if (not smoothLevel) then
|
||||
while (_i <= #content-2) do
|
||||
local v = (content[_i-2]+content[_i-1]+content[_i]+content[_i+1]+content[_i+2])/5 --normalize
|
||||
_data [#_data+1] = {scaleW*(_i-2), v/graphMaxDps} --x and y coords
|
||||
_i = _i + 1
|
||||
while (index <= #content-2) do
|
||||
local value = (content[index-2] + content[index-1] + content[index] + content[index+1] + content[index+2]) / 5 --normalize
|
||||
builtData[#builtData+1] = {scaleWidth * (index-2), value / graphMaxDps} -- x and y coords
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
elseif (smoothLevel == "SHORT") then
|
||||
while (_i <= #content-2) do
|
||||
local value = (content[_i] + content[_i+1]) / 2
|
||||
_data [#_data+1] = {scaleW*(_i-2), value}
|
||||
_data [#_data+1] = {scaleW*(_i-2), value}
|
||||
_i = _i + 2
|
||||
while (index <= #content-2) do
|
||||
local value = (content[index] + content[index+1]) / 2
|
||||
builtData [#builtData+1] = {scaleWidth*(index-2), value}
|
||||
builtData [#builtData+1] = {scaleWidth*(index-2), value}
|
||||
index = index + 2
|
||||
end
|
||||
|
||||
elseif (smoothLevel == "SMA") then
|
||||
reset_SMA()
|
||||
while (_i <= #content-2) do
|
||||
local value, is_new_max_value = do_SMA (content[_i], max_value)
|
||||
while (index <= #content-2) do
|
||||
local value, is_new_max_value = do_SMA(content[index], maxValue)
|
||||
if (is_new_max_value) then
|
||||
max_value = is_new_max_value
|
||||
maxValue = is_new_max_value
|
||||
end
|
||||
_data [#_data+1] = {scaleW*(_i-2), value} --x and y coords
|
||||
_i = _i + 1
|
||||
builtData [#builtData+1] = {scaleWidth * (index-2), value} -- x and y coords
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
elseif (smoothLevel == -1) then
|
||||
while (_i <= #content-2) do
|
||||
local current = content[_i]
|
||||
while (index <= #content-2) do
|
||||
local current = content[index]
|
||||
|
||||
local minus_2 = content[_i-2] * 0.6
|
||||
local minus_1 = content[_i-1] * 0.8
|
||||
local plus_1 = content[_i+1] * 0.8
|
||||
local plus_2 = content[_i+2] * 0.6
|
||||
local minus_2 = content[index-2] * 0.6
|
||||
local minus_1 = content[index-1] * 0.8
|
||||
local plus_1 = content[index+1] * 0.8
|
||||
local plus_2 = content[index+2] * 0.6
|
||||
|
||||
local v = (current + minus_2 + minus_1 + plus_1 + plus_2)/5 --normalize
|
||||
_data [#_data+1] = {scaleW*(_i-2), v/graphMaxDps} --x and y coords
|
||||
_i = _i + 1
|
||||
local value = (current + minus_2 + minus_1 + plus_1 + plus_2) / 5 --normalize
|
||||
builtData [#builtData+1] = {scaleWidth * (index-2), value / graphMaxDps} -- x and y coords
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
elseif (smoothLevel == 1) then
|
||||
_i = 2
|
||||
while (_i <= #content-1) do
|
||||
local v = (content[_i-1]+content[_i]+content[_i+1])/3 --normalize
|
||||
_data [#_data+1] = {scaleW*(_i-1), v/graphMaxDps} --x and y coords
|
||||
_i = _i + 1
|
||||
index = 2
|
||||
while (index <= #content-1) do
|
||||
local value = (content[index-1]+content[index]+content[index+1])/3 --normalize
|
||||
builtData [#builtData+1] = {scaleWidth*(index-1), value/graphMaxDps} -- x and y coords
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
elseif (smoothLevel == 2) then
|
||||
_i = 1
|
||||
while (_i <= #content) do
|
||||
local v = content[_i] --do not normalize
|
||||
_data [#_data+1] = {scaleW*(_i), v/graphMaxDps} --x and y coords
|
||||
_i = _i + 1
|
||||
index = 1
|
||||
while (index <= #content) do
|
||||
local value = content[index] --do not normalize
|
||||
builtData [#builtData+1] = {scaleWidth*(index), value/graphMaxDps} -- x and y coords
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tremove(content, 1)
|
||||
@@ -2957,55 +2955,46 @@ local chart_panel_add_data = function(self, graphicData, color, name, elapsed_ti
|
||||
tremove(content, #graphicData)
|
||||
tremove(content, #graphicData)
|
||||
|
||||
if (max_value > self.max_value) then
|
||||
if (maxValue > LibGraphChartFrame.max_value) then
|
||||
--normalize previous data
|
||||
if (self.max_value > 0) then
|
||||
local normalizePercent = self.max_value / max_value
|
||||
for dataIndex, Data in ipairs(self.Data) do
|
||||
if (LibGraphChartFrame.max_value > 0) then
|
||||
local normalizePercent = LibGraphChartFrame.max_value / maxValue
|
||||
for dataIndex, Data in ipairs(LibGraphChartFrame.Data) do
|
||||
local Points = Data.Points
|
||||
for i = 1, #Points do
|
||||
Points[i][2] = Points[i][2]*normalizePercent
|
||||
Points[i][2] = Points[i][2] * normalizePercent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.max_value = max_value
|
||||
f:SetScale(max_value)
|
||||
LibGraphChartFrame.max_value = maxValue
|
||||
chartPanel:SetScale(maxValue)
|
||||
end
|
||||
|
||||
tinsert(f.GData, {_data, color or line_default_color, lineTexture, max_value, elapsed_time})
|
||||
tinsert(chartPanel.GData, {builtData, color or line_default_color, lineTexture, maxValue, elapsedTime})
|
||||
if (name) then
|
||||
f:AddLabel (color or line_default_color, name, "graphic", #f.GData)
|
||||
chartPanel:AddLabel(color or line_default_color, name, "graphic", #chartPanel.GData)
|
||||
end
|
||||
|
||||
local newLineTexture = "Interface\\AddOns\\Details\\Libs\\LibGraph-2.0\\line"
|
||||
|
||||
if (firstIndex) then
|
||||
if (lineTexture) then
|
||||
if (not lineTexture:find("\\") and not lineTexture:find("//")) then
|
||||
local path = string.match(debugstack (1, 1, 0), "AddOns\\(.+)LibGraph%-2%.0%.lua")
|
||||
if path then
|
||||
lineTexture = "Interface\\AddOns\\" .. path .. lineTexture
|
||||
else
|
||||
lineTexture = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.insert (self.Data, 1, {Points = _data, Color = color or line_default_color, lineTexture = lineTexture, ElapsedTime = elapsed_time})
|
||||
self.NeedsUpdate = true
|
||||
table.insert(LibGraphChartFrame.Data, 1, {Points = builtData, Color = color or line_default_color, lineTexture = newLineTexture, ElapsedTime = elapsedTime})
|
||||
LibGraphChartFrame.NeedsUpdate = true
|
||||
else
|
||||
self:AddDataSeries (_data, color or line_default_color, nil, lineTexture)
|
||||
self.Data [#self.Data].ElapsedTime = elapsed_time
|
||||
LibGraphChartFrame:AddDataSeries(builtData, color or line_default_color, nil, newLineTexture)
|
||||
LibGraphChartFrame.Data[#LibGraphChartFrame.Data].ElapsedTime = elapsedTime
|
||||
end
|
||||
|
||||
local max_time = 0
|
||||
for _, data in ipairs(self.Data) do
|
||||
if (data.ElapsedTime > max_time) then
|
||||
max_time = data.ElapsedTime
|
||||
local maxTime = 0
|
||||
for _, data in ipairs(LibGraphChartFrame.Data) do
|
||||
if (data.ElapsedTime > maxTime) then
|
||||
maxTime = data.ElapsedTime
|
||||
end
|
||||
end
|
||||
|
||||
f:SetTime(max_time)
|
||||
chart_panel_onresize (f)
|
||||
chartPanel:SetTime(maxTime)
|
||||
chart_panel_onresize(chartPanel)
|
||||
end
|
||||
|
||||
|
||||
@@ -3061,50 +3050,50 @@ local chart_panel_right_click_close = function(self, value)
|
||||
end
|
||||
end
|
||||
|
||||
function detailsFramework:CreateChartPanel(parent, w, h, name)
|
||||
function detailsFramework:CreateChartPanel(parent, width, height, name)
|
||||
if (not name) then
|
||||
name = "DFPanel" .. detailsFramework.PanelCounter
|
||||
detailsFramework.PanelCounter = detailsFramework.PanelCounter + 1
|
||||
end
|
||||
|
||||
parent = parent or UIParent
|
||||
w = w or 800
|
||||
h = h or 500
|
||||
width = width or 800
|
||||
height = height or 500
|
||||
|
||||
local f = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
f:SetSize(w or 500, h or 400)
|
||||
f:EnableMouse(true)
|
||||
f:SetMovable(true)
|
||||
local chartFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
chartFrame:SetSize(width or 500, height or 400)
|
||||
chartFrame:EnableMouse(true)
|
||||
chartFrame:SetMovable(true)
|
||||
|
||||
f:SetScript("OnMouseDown", chart_panel_mousedown)
|
||||
f:SetScript("OnMouseUp", chart_panel_mouseup)
|
||||
chartFrame:SetScript("OnMouseDown", chart_panel_mousedown)
|
||||
chartFrame:SetScript("OnMouseUp", chart_panel_mouseup)
|
||||
|
||||
f:SetBackdrop(chart_panel_backdrop)
|
||||
f:SetBackdropColor(.3, .3, .3, .3)
|
||||
chartFrame:SetBackdrop(chart_panel_backdrop)
|
||||
chartFrame:SetBackdropColor(.3, .3, .3, .3)
|
||||
|
||||
local c = CreateFrame("Button", nil, f, "UIPanelCloseButton", "BackdropTemplate")
|
||||
c:SetWidth(32)
|
||||
c:SetHeight(32)
|
||||
c:SetPoint("TOPRIGHT", f, "TOPRIGHT", -3, -7)
|
||||
c:SetFrameLevel(f:GetFrameLevel()+1)
|
||||
c:SetAlpha(0.9)
|
||||
f.CloseButton = c
|
||||
local closeButton = CreateFrame("Button", nil, chartFrame, "UIPanelCloseButton", "BackdropTemplate")
|
||||
closeButton:SetWidth(32)
|
||||
closeButton:SetHeight(32)
|
||||
closeButton:SetPoint("TOPRIGHT", chartFrame, "TOPRIGHT", -3, -7)
|
||||
closeButton:SetFrameLevel(chartFrame:GetFrameLevel()+1)
|
||||
closeButton:SetAlpha(0.9)
|
||||
chartFrame.CloseButton = closeButton
|
||||
|
||||
local title = detailsFramework:NewLabel(f, nil, "$parentTitle", "chart_title", "Chart!", nil, 20, {1, 1, 0})
|
||||
title:SetPoint("topleft", f, "topleft", 110, -13)
|
||||
local title = detailsFramework:NewLabel(chartFrame, nil, "$parentTitle", "chart_title", "Chart!", nil, 20, {1, 1, 0})
|
||||
title:SetPoint("topleft", chartFrame, "topleft", 110, -13)
|
||||
|
||||
f.Overlays = {}
|
||||
f.OverlaysAmount = 1
|
||||
chartFrame.Overlays = {}
|
||||
chartFrame.OverlaysAmount = 1
|
||||
|
||||
f.BoxLabels = {}
|
||||
f.BoxLabelsAmount = 1
|
||||
chartFrame.BoxLabels = {}
|
||||
chartFrame.BoxLabelsAmount = 1
|
||||
|
||||
f.ShowHeader = true
|
||||
f.HeaderOnlyIndicator = false
|
||||
f.HeaderShowOverlays = true
|
||||
chartFrame.ShowHeader = true
|
||||
chartFrame.HeaderOnlyIndicator = false
|
||||
chartFrame.HeaderShowOverlays = true
|
||||
|
||||
--graphic
|
||||
local g = LibStub:GetLibrary("LibGraph-2.0"):CreateGraphLine (name .. "Graphic", f, "topleft","topleft", 108, -35, w - 120, h - 67)
|
||||
local g = LibStub:GetLibrary("LibGraph-2.0"):CreateGraphLine (name .. "Graphic", chartFrame, "topleft","topleft", 108, -35, width - 120, height - 67)
|
||||
g:SetXAxis (-1,1)
|
||||
g:SetYAxis (-1,1)
|
||||
g:SetGridSpacing (false, false)
|
||||
@@ -3122,10 +3111,10 @@ function detailsFramework:CreateChartPanel(parent, w, h, name)
|
||||
|
||||
g:SetLineTexture ("line")
|
||||
|
||||
f.Graphic = g
|
||||
f.GData = {}
|
||||
f.OData = {}
|
||||
f.ChartFrames = {}
|
||||
chartFrame.Graphic = g
|
||||
chartFrame.GData = {}
|
||||
chartFrame.OData = {}
|
||||
chartFrame.ChartFrames = {}
|
||||
|
||||
--div lines
|
||||
for i = 1, 8, 1 do
|
||||
@@ -3134,10 +3123,10 @@ function detailsFramework:CreateChartPanel(parent, w, h, name)
|
||||
line:SetWidth(670)
|
||||
line:SetHeight(1.1)
|
||||
|
||||
local s = f:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
f ["dpsamt"..i] = s
|
||||
local s = chartFrame:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
chartFrame ["dpsamt"..i] = s
|
||||
s:SetText("100k")
|
||||
s:SetPoint("topleft", f, "topleft", 27, -61 + (-(24.6*i)))
|
||||
s:SetPoint("topleft", chartFrame, "topleft", 27, -61 + (-(24.6*i)))
|
||||
|
||||
line:SetPoint("topleft", s, "bottom", -27, 0)
|
||||
line:SetPoint("topright", g, "right", 0, 0)
|
||||
@@ -3145,49 +3134,49 @@ function detailsFramework:CreateChartPanel(parent, w, h, name)
|
||||
end
|
||||
|
||||
--create time labels and the bottom texture to use as a background to these labels
|
||||
f.TimeLabels = {}
|
||||
f.TimeLabelsHeight = 16
|
||||
chartFrame.TimeLabels = {}
|
||||
chartFrame.TimeLabelsHeight = 16
|
||||
|
||||
for i = 1, 17 do
|
||||
local timeString = f:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
local timeString = chartFrame:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
timeString:SetText("00:00")
|
||||
timeString:SetPoint("bottomleft", f, "bottomleft", 78 + ((i-1)*36), f.TimeLabelsHeight)
|
||||
f.TimeLabels [i] = timeString
|
||||
timeString:SetPoint("bottomleft", chartFrame, "bottomleft", 78 + ((i-1)*36), chartFrame.TimeLabelsHeight)
|
||||
chartFrame.TimeLabels [i] = timeString
|
||||
|
||||
local line = f:CreateTexture(nil, "border")
|
||||
line:SetSize(1, h-45)
|
||||
local line = chartFrame:CreateTexture(nil, "border")
|
||||
line:SetSize(1, height-45)
|
||||
line:SetColorTexture(1, 1, 1, .1)
|
||||
line:SetPoint("bottomleft", timeString, "topright", 0, -10)
|
||||
line:Hide()
|
||||
timeString.line = line
|
||||
end
|
||||
|
||||
local bottom_texture = detailsFramework:NewImage(f, nil, 702, 25, "background", nil, nil, "$parentBottomTexture")
|
||||
local bottom_texture = detailsFramework:NewImage(chartFrame, nil, 702, 25, "background", nil, nil, "$parentBottomTexture")
|
||||
bottom_texture:SetColorTexture(.1, .1, .1, .7)
|
||||
bottom_texture:SetPoint("topright", g, "bottomright", 0, 0)
|
||||
bottom_texture:SetPoint("bottomleft", f, "bottomleft", 8, 12)
|
||||
bottom_texture:SetPoint("bottomleft", chartFrame, "bottomleft", 8, 12)
|
||||
|
||||
|
||||
|
||||
f.SetTime = chart_panel_align_timelabels
|
||||
f.EnableVerticalLines = chart_panel_vlines_on
|
||||
f.DisableVerticalLines = chart_panel_vlines_off
|
||||
f.SetTitle = chart_panel_set_title
|
||||
f.SetScale = chart_panel_set_scale
|
||||
f.Reset = chart_panel_reset
|
||||
f.AddLine = chart_panel_add_data
|
||||
f.CanMove = chart_panel_can_move
|
||||
f.AddLabel = chart_panel_add_label
|
||||
f.AddOverlay = chart_panel_add_overlay
|
||||
f.HideCloseButton = chart_panel_hide_close_button
|
||||
f.RightClickClose = chart_panel_right_click_close
|
||||
f.CalcStdDev = calc_stddev
|
||||
f.CalcLowessSmoothing = calc_lowess_smoothing
|
||||
chartFrame.SetTime = chart_panel_align_timelabels
|
||||
chartFrame.EnableVerticalLines = chart_panel_vlines_on
|
||||
chartFrame.DisableVerticalLines = chart_panel_vlines_off
|
||||
chartFrame.SetTitle = chart_panel_set_title
|
||||
chartFrame.SetScale = chart_panel_set_scale
|
||||
chartFrame.Reset = chart_panel_reset
|
||||
chartFrame.AddLine = chart_panel_add_data
|
||||
chartFrame.CanMove = chart_panel_can_move
|
||||
chartFrame.AddLabel = chart_panel_add_label
|
||||
chartFrame.AddOverlay = chart_panel_add_overlay
|
||||
chartFrame.HideCloseButton = chart_panel_hide_close_button
|
||||
chartFrame.RightClickClose = chart_panel_right_click_close
|
||||
chartFrame.CalcStdDev = calc_stddev
|
||||
chartFrame.CalcLowessSmoothing = calc_lowess_smoothing
|
||||
|
||||
f:SetScript("OnSizeChanged", chart_panel_onresize)
|
||||
chart_panel_onresize(f)
|
||||
chartFrame:SetScript("OnSizeChanged", chart_panel_onresize)
|
||||
chart_panel_onresize(chartFrame)
|
||||
|
||||
return f
|
||||
return chartFrame
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -3264,13 +3253,13 @@ local gframe_create_line = function(self)
|
||||
textBackground:SetColorTexture(0, 0, 0, 0.5)
|
||||
textBackground:SetPoint("bottom", f.ball, "top", 0, -6)
|
||||
text:SetPoint("center", textBackground, "center")
|
||||
detailsFramework:SetFontSize (text, 10)
|
||||
detailsFramework:SetFontSize(text, 10)
|
||||
f.text = text
|
||||
f.textBackground = textBackground
|
||||
|
||||
local timeline = f:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
timeline:SetPoint("bottomright", f, "bottomright", -2, 0)
|
||||
detailsFramework:SetFontSize (timeline, 8)
|
||||
detailsFramework:SetFontSize(timeline, 8)
|
||||
f.timeline = timeline
|
||||
|
||||
return f
|
||||
@@ -3351,34 +3340,32 @@ local gframe_update = function(self, lines)
|
||||
|
||||
o = o + 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function detailsFramework:CreateGFrame (parent, w, h, linewidth, onenter, onleave, member, name)
|
||||
local f = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
f:SetSize(w or 450, h or 150)
|
||||
--f.CustomLine = [[Interface\AddOns\Details\Libs\LibGraph-2.0\line]]
|
||||
function detailsFramework:CreateGFrame(parent, width, height, lineWidth, onEnter, onLeave, member, name)
|
||||
local newGraphicFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
newGraphicFrame:SetSize(width or 450, height or 150)
|
||||
|
||||
if (member) then
|
||||
parent [member] = f
|
||||
parent[member] = newGraphicFrame
|
||||
end
|
||||
|
||||
f.CreateLine = gframe_create_line
|
||||
f.GetLine = gframe_getline
|
||||
f.Reset = gframe_reset
|
||||
f.UpdateLines = gframe_update
|
||||
newGraphicFrame.CreateLine = gframe_create_line
|
||||
newGraphicFrame.GetLine = gframe_getline
|
||||
newGraphicFrame.Reset = gframe_reset
|
||||
newGraphicFrame.UpdateLines = gframe_update
|
||||
|
||||
f.MaxValue = 0
|
||||
newGraphicFrame.MaxValue = 0
|
||||
|
||||
f._lines = {}
|
||||
newGraphicFrame._lines = {}
|
||||
|
||||
f._onenter_line = onenter
|
||||
f._onleave_line = onleave
|
||||
newGraphicFrame._onenter_line = onEnter
|
||||
newGraphicFrame._onleave_line = onLeave
|
||||
|
||||
f._linewidth = linewidth or 50
|
||||
f._maxlines = floor(f:GetWidth() / f._linewidth)
|
||||
newGraphicFrame._linewidth = lineWidth or 50
|
||||
newGraphicFrame._maxlines = floor(newGraphicFrame:GetWidth() / newGraphicFrame._linewidth)
|
||||
|
||||
return f
|
||||
return newGraphicFrame
|
||||
end
|
||||
|
||||
|
||||
@@ -4500,7 +4487,7 @@ detailsFramework.TitleFunctions = {
|
||||
end
|
||||
|
||||
if (size) then
|
||||
detailsFramework:SetFontSize (self.TitleLabel, size)
|
||||
detailsFramework:SetFontSize(self.TitleLabel, size)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4683,7 +4670,7 @@ detailsFramework.IconRowFunctions = {
|
||||
iconFrame.CountdownText:SetText(formattedTime)
|
||||
|
||||
iconFrame.CountdownText:SetPoint(self.options.text_anchor or "center", iconFrame, self.options.text_rel_anchor or "center", self.options.text_x_offset or 0, self.options.text_y_offset or 0)
|
||||
detailsFramework:SetFontSize (iconFrame.CountdownText, self.options.text_size)
|
||||
detailsFramework:SetFontSize(iconFrame.CountdownText, self.options.text_size)
|
||||
detailsFramework:SetFontFace (iconFrame.CountdownText, self.options.text_font)
|
||||
detailsFramework:SetFontOutline (iconFrame.CountdownText, self.options.text_outline)
|
||||
|
||||
@@ -4715,7 +4702,7 @@ detailsFramework.IconRowFunctions = {
|
||||
iconFrame.Desc:SetText(descText.text)
|
||||
iconFrame.Desc:SetTextColor(detailsFramework:ParseColors(descText.text_color or self.options.desc_text_color))
|
||||
iconFrame.Desc:SetPoint(self.options.desc_text_anchor or "bottom", iconFrame, self.options.desc_text_rel_anchor or "top", self.options.desc_text_x_offset or 0, self.options.desc_text_y_offset or 2)
|
||||
detailsFramework:SetFontSize (iconFrame.Desc, descText.text_size or self.options.desc_text_size)
|
||||
detailsFramework:SetFontSize(iconFrame.Desc, descText.text_size or self.options.desc_text_size)
|
||||
detailsFramework:SetFontFace (iconFrame.Desc, self.options.desc_text_font)
|
||||
detailsFramework:SetFontOutline (iconFrame.Desc, self.options.desc_text_outline)
|
||||
else
|
||||
@@ -4727,7 +4714,7 @@ detailsFramework.IconRowFunctions = {
|
||||
iconFrame.StackText:SetText(count)
|
||||
iconFrame.StackText:SetTextColor(detailsFramework:ParseColors(self.options.desc_text_color))
|
||||
iconFrame.StackText:SetPoint(self.options.stack_text_anchor or "center", iconFrame, self.options.stack_text_rel_anchor or "bottomright", self.options.stack_text_x_offset or 0, self.options.stack_text_y_offset or 0)
|
||||
detailsFramework:SetFontSize (iconFrame.StackText, self.options.stack_text_size)
|
||||
detailsFramework:SetFontSize(iconFrame.StackText, self.options.stack_text_size)
|
||||
detailsFramework:SetFontFace (iconFrame.StackText, self.options.stack_text_font)
|
||||
detailsFramework:SetFontOutline (iconFrame.StackText, self.options.stack_text_outline)
|
||||
else
|
||||
@@ -7416,7 +7403,7 @@ detailsFramework.PowerFrameFunctions = {
|
||||
self.percentText:Show()
|
||||
PixelUtil.SetPoint(self.percentText, "center", self, "center", 0, 0)
|
||||
|
||||
detailsFramework:SetFontSize (self.percentText, 9)
|
||||
detailsFramework:SetFontSize(self.percentText, 9)
|
||||
detailsFramework:SetFontColor(self.percentText, "white")
|
||||
detailsFramework:SetFontOutline (self.percentText, "OUTLINE")
|
||||
else
|
||||
@@ -8630,7 +8617,7 @@ detailsFramework.BorderFunctions = {
|
||||
|
||||
-- ~borderframe
|
||||
function detailsFramework:CreateBorderFrame (parent, name)
|
||||
local parentName = name or "DetailsFrameworkBorderFrame" .. tostring(math.random (1, 100000000))
|
||||
local parentName = name or "DetailsFrameworkBorderFrame" .. tostring(math.random(1, 100000000))
|
||||
|
||||
local f = CreateFrame("frame", parentName, parent, "BackdropTemplate")
|
||||
f:SetFrameLevel(f:GetFrameLevel()+1)
|
||||
@@ -9131,7 +9118,7 @@ end
|
||||
-- ~unitframe
|
||||
local globalBaseFrameLevel = 1 -- to be increased + used across each new plate
|
||||
function detailsFramework:CreateUnitFrame(parent, name, unitFrameSettingsOverride, healthBarSettingsOverride, castBarSettingsOverride, powerBarSettingsOverride)
|
||||
local parentName = name or ("DetailsFrameworkUnitFrame" .. tostring(math.random (1, 100000000)))
|
||||
local parentName = name or ("DetailsFrameworkUnitFrame" .. tostring(math.random(1, 100000000)))
|
||||
|
||||
--create the main unit frame
|
||||
local mewUnitFrame = CreateFrame("button", parentName, parent, "BackdropTemplate")
|
||||
@@ -9281,7 +9268,7 @@ detailsFramework.TimeLineElapsedTimeFunctions = {
|
||||
end
|
||||
|
||||
detailsFramework:SetFontColor(label, self.options.text_color)
|
||||
detailsFramework:SetFontSize (label, self.options.text_size)
|
||||
detailsFramework:SetFontSize(label, self.options.text_size)
|
||||
detailsFramework:SetFontFace (label, self.options.text_font)
|
||||
detailsFramework:SetFontOutline (label, self.options.text_outline)
|
||||
|
||||
@@ -9325,7 +9312,7 @@ detailsFramework.TimeLineElapsedTimeFunctions = {
|
||||
|
||||
local secondsOfTime = pixelPerSecond * xOffset
|
||||
|
||||
label:SetText(detailsFramework:IntegerToTimer (floor(secondsOfTime)))
|
||||
label:SetText(detailsFramework:IntegerToTimer(floor(secondsOfTime)))
|
||||
|
||||
if (label.line:IsShown()) then
|
||||
label.line:SetHeight(parent:GetParent():GetHeight())
|
||||
|
||||
+58
-63
@@ -1,5 +1,5 @@
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
@@ -12,7 +12,7 @@ local CreateImageEditorFrame = function()
|
||||
editorWindow:SetPoint("center", UIParent, "center")
|
||||
editorWindow:SetResizable(true)
|
||||
editorWindow:SetMovable(true)
|
||||
editorWindow:SetClampedToScreen (true)
|
||||
editorWindow:SetClampedToScreen(true)
|
||||
tinsert(UISpecialFrames, "DetailsFrameworkImageEdit")
|
||||
editorWindow:SetFrameStrata("TOOLTIP")
|
||||
|
||||
@@ -23,26 +23,26 @@ local CreateImageEditorFrame = function()
|
||||
end
|
||||
|
||||
_G.DetailsFrameworkImageEditTable = editorWindow
|
||||
|
||||
|
||||
editorWindow.hooks = {}
|
||||
|
||||
|
||||
local background = DF:NewImage(editorWindow, nil, nil, nil, "background", nil, "background", "$parentBackground")
|
||||
background:SetAllPoints()
|
||||
background:SetTexture(0, 0, 0, .8)
|
||||
|
||||
|
||||
local edit_texture = DF:NewImage(editorWindow, nil, 500, 500, "artwork", nil, "edit_texture", "$parentImage")
|
||||
edit_texture:SetAllPoints()
|
||||
_G.DetailsFrameworkImageEdit_EditTexture = edit_texture
|
||||
|
||||
|
||||
local background_frame = CreateFrame("frame", "DetailsFrameworkImageEditBackground", DetailsFrameworkImageEdit, "BackdropTemplate")
|
||||
background_frame:SetPoint("topleft", DetailsFrameworkImageEdit, "topleft", -10, 30)
|
||||
background_frame:SetFrameStrata("TOOLTIP")
|
||||
background_frame:SetFrameLevel(editorWindow:GetFrameLevel())
|
||||
background_frame:SetSize(790, 560)
|
||||
|
||||
|
||||
background_frame:SetResizable(true)
|
||||
background_frame:SetMovable(true)
|
||||
|
||||
|
||||
background_frame:SetScript("OnMouseDown", function()
|
||||
editorWindow:StartMoving()
|
||||
end)
|
||||
@@ -60,16 +60,15 @@ local CreateImageEditorFrame = function()
|
||||
|
||||
local haveHFlip = false
|
||||
local haveVFlip = false
|
||||
|
||||
|
||||
--Top Slider
|
||||
|
||||
local topCoordTexture = DF:NewImage(editorWindow, nil, nil, nil, "overlay", nil, nil, "$parentImageTopCoord")
|
||||
topCoordTexture:SetPoint("topleft", editorWindow, "topleft")
|
||||
topCoordTexture:SetPoint("topright", editorWindow, "topright")
|
||||
topCoordTexture:SetColorTexture(1, 0, 0)
|
||||
topCoordTexture.height = 1
|
||||
topCoordTexture.alpha = .2
|
||||
|
||||
|
||||
local topSlider = DF:NewSlider (editorWindow, nil, "$parentTopSlider", "topSlider", 100, 100, 0.1, 100, 0.1, 0)
|
||||
topSlider:SetAllPoints(editorWindow.widget)
|
||||
topSlider:SetOrientation ("VERTICAL")
|
||||
@@ -90,11 +89,10 @@ local CreateImageEditorFrame = function()
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
topSlider:Hide()
|
||||
|
||||
--Bottom Slider
|
||||
|
||||
local bottomCoordTexture = DF:NewImage(editorWindow, nil, nil, nil, "overlay", nil, nil, "$parentImageBottomCoord")
|
||||
bottomCoordTexture:SetPoint("bottomleft", editorWindow, "bottomleft", 0, 0)
|
||||
bottomCoordTexture:SetPoint("bottomright", editorWindow, "bottomright", 0, 0)
|
||||
@@ -102,7 +100,7 @@ local CreateImageEditorFrame = function()
|
||||
bottomCoordTexture.height = 1
|
||||
bottomCoordTexture.alpha = .2
|
||||
|
||||
local bottomSlider= DF:NewSlider (editorWindow, nil, "$parentBottomSlider", "bottomSlider", 100, 100, 0.1, 100, 0.1, 100)
|
||||
local bottomSlider = DF:NewSlider (editorWindow, nil, "$parentBottomSlider", "bottomSlider", 100, 100, 0.1, 100, 0.1, 100)
|
||||
bottomSlider:SetAllPoints(editorWindow.widget)
|
||||
bottomSlider:SetOrientation ("VERTICAL")
|
||||
bottomSlider.backdrop = nil
|
||||
@@ -123,49 +121,47 @@ local CreateImageEditorFrame = function()
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
bottomSlider:Hide()
|
||||
|
||||
|
||||
--Left Slider
|
||||
|
||||
local leftCoordTexture = DF:NewImage(editorWindow, nil, nil, nil, "overlay", nil, nil, "$parentImageLeftCoord")
|
||||
leftCoordTexture:SetPoint("topleft", editorWindow, "topleft", 0, 0)
|
||||
leftCoordTexture:SetPoint("bottomleft", editorWindow, "bottomleft", 0, 0)
|
||||
leftCoordTexture:SetColorTexture(1, 0, 0)
|
||||
leftCoordTexture.width = 1
|
||||
leftCoordTexture.alpha = .2
|
||||
|
||||
|
||||
local leftSlider = DF:NewSlider (editorWindow, nil, "$parentLeftSlider", "leftSlider", 100, 100, 0.1, 100, 0.1, 0.1)
|
||||
leftSlider:SetAllPoints(editorWindow.widget)
|
||||
leftSlider.backdrop = nil
|
||||
leftSlider.fractional = true
|
||||
leftSlider:SetHook("OnEnter", function() return true end)
|
||||
leftSlider:SetHook("OnLeave", function() return true end)
|
||||
|
||||
|
||||
local leftSliderThumpTexture = leftSlider:CreateTexture(nil, "overlay")
|
||||
leftSliderThumpTexture:SetColorTexture(1, 1, 1)
|
||||
leftSliderThumpTexture:SetWidth(1)
|
||||
leftSliderThumpTexture:SetHeight(512)
|
||||
leftSlider:SetThumbTexture (leftSliderThumpTexture)
|
||||
|
||||
|
||||
leftSlider:SetHook("OnValueChange", function(_, _, value)
|
||||
leftCoordTexture.image:SetWidth(editorWindow.frame:GetWidth()/100*value)
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
leftSlider:Hide()
|
||||
|
||||
|
||||
--Right Slider
|
||||
|
||||
local rightCoordTexture = DF:NewImage(editorWindow, nil, nil, nil, "overlay", nil, nil, "$parentImageRightCoord")
|
||||
rightCoordTexture:SetPoint("topright", editorWindow, "topright", 0, 0)
|
||||
rightCoordTexture:SetPoint("bottomright", editorWindow, "bottomright", 0, 0)
|
||||
rightCoordTexture:SetColorTexture(1, 0, 0)
|
||||
rightCoordTexture.width = 1
|
||||
rightCoordTexture.alpha = .2
|
||||
|
||||
|
||||
local rightSlider = DF:NewSlider (editorWindow, nil, "$parentRightSlider", "rightSlider", 100, 100, 0.1, 100, 0.1, 100)
|
||||
rightSlider:SetAllPoints(editorWindow.widget)
|
||||
rightSlider.backdrop = nil
|
||||
@@ -186,11 +182,10 @@ local CreateImageEditorFrame = function()
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
rightSlider:Hide()
|
||||
|
||||
--Edit Buttons
|
||||
|
||||
rightSlider:Hide()
|
||||
|
||||
--Edit Buttons
|
||||
local buttonsBackground = DF:NewPanel(UIParent, nil, "DetailsFrameworkImageEditButtonsBg", nil, 115, 230)
|
||||
--buttonsBackground:SetPoint("topleft", window, "topright", 2, 0)
|
||||
buttonsBackground:SetPoint("topright", background_frame, "topright", -8, -10)
|
||||
@@ -198,35 +193,35 @@ local CreateImageEditorFrame = function()
|
||||
--buttonsBackground:SetMovable(true)
|
||||
tinsert(UISpecialFrames, "DetailsFrameworkImageEditButtonsBg")
|
||||
buttonsBackground:SetFrameStrata("TOOLTIP")
|
||||
|
||||
|
||||
local alphaFrameShown = false
|
||||
|
||||
|
||||
local editingSide = nil
|
||||
local lastButton = nil
|
||||
local alphaFrame
|
||||
local originalColor = {0.9999, 0.8196, 0}
|
||||
|
||||
|
||||
local enableTexEdit = function(button, bottom, side)
|
||||
|
||||
|
||||
if (alphaFrameShown) then
|
||||
alphaFrame:Hide()
|
||||
alphaFrameShown = false
|
||||
button.text:SetTextColor(unpack(originalColor))
|
||||
end
|
||||
|
||||
|
||||
if (ColorPickerFrame:IsShown()) then
|
||||
ColorPickerFrame:Hide()
|
||||
end
|
||||
|
||||
|
||||
if (lastButton) then
|
||||
lastButton.text:SetTextColor(unpack(originalColor))
|
||||
end
|
||||
|
||||
|
||||
if (editingSide == side) then
|
||||
editorWindow [editingSide.."Slider"]:Hide()
|
||||
editingSide = nil
|
||||
return
|
||||
|
||||
|
||||
elseif (editingSide) then
|
||||
editorWindow [editingSide.."Slider"]:Hide()
|
||||
end
|
||||
@@ -234,10 +229,10 @@ local CreateImageEditorFrame = function()
|
||||
editingSide = side
|
||||
button.text:SetTextColor(1, 1, 1)
|
||||
lastButton = button
|
||||
|
||||
|
||||
editorWindow [side.."Slider"]:Show()
|
||||
end
|
||||
|
||||
|
||||
local yMod = -10
|
||||
|
||||
local leftTexCoordButton = DF:NewButton(buttonsBackground, nil, "$parentLeftTexButton", nil, 100, 20, enableTexEdit, "left", nil, nil, "Crop Left", 1)
|
||||
@@ -255,11 +250,11 @@ local CreateImageEditorFrame = function()
|
||||
local bottomTexCoordButton = DF:NewButton(buttonsBackground, nil, "$parentBottomTexButton", nil, 100, 20, enableTexEdit, "bottom", nil, nil, "Crop Bottom", 1)
|
||||
bottomTexCoordButton:SetPoint("topright", buttonsBackground, "topright", -8, -70 + yMod)
|
||||
bottomTexCoordButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
|
||||
local Alpha = DF:NewButton(buttonsBackground, nil, "$parentBottomAlphaButton", nil, 100, 20, alpha, nil, nil, nil, "Alpha", 1)
|
||||
Alpha:SetPoint("topright", buttonsBackground, "topright", -8, -115 + yMod)
|
||||
Alpha:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
|
||||
--overlay color
|
||||
local selectedColor = function(default)
|
||||
if (default) then
|
||||
@@ -274,14 +269,14 @@ local CreateImageEditorFrame = function()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local changeColor = function()
|
||||
|
||||
|
||||
ColorPickerFrame.func = nil
|
||||
ColorPickerFrame.opacityFunc = nil
|
||||
ColorPickerFrame.cancelFunc = nil
|
||||
ColorPickerFrame.previousValues = nil
|
||||
|
||||
|
||||
local right, g, bottom = edit_texture:GetVertexColor()
|
||||
ColorPickerFrame:SetColorRGB (right, g, bottom)
|
||||
ColorPickerFrame:SetParent(buttonsBackground.widget)
|
||||
@@ -292,13 +287,13 @@ local CreateImageEditorFrame = function()
|
||||
ColorPickerFrame:ClearAllPoints()
|
||||
ColorPickerFrame:SetPoint("left", buttonsBackground.widget, "right")
|
||||
ColorPickerFrame:Show()
|
||||
|
||||
|
||||
if (alphaFrameShown) then
|
||||
alphaFrame:Hide()
|
||||
alphaFrameShown = false
|
||||
Alpha.button.text:SetTextColor(unpack(originalColor))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (lastButton) then
|
||||
lastButton.text:SetTextColor(unpack(originalColor))
|
||||
if (editingSide) then
|
||||
@@ -306,34 +301,34 @@ local CreateImageEditorFrame = function()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local changeColorButton = DF:NewButton(buttonsBackground, nil, "$parentOverlayColorButton", nil, 100, 20, changeColor, nil, nil, nil, "Color", 1)
|
||||
changeColorButton:SetPoint("topright", buttonsBackground, "topright", -8, -95 + yMod)
|
||||
changeColorButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
|
||||
alphaFrame = DF:NewPanel(buttonsBackground, nil, "DetailsFrameworkImageEditAlphaBg", nil, 40, 225)
|
||||
alphaFrame:SetPoint("topleft", buttonsBackground, "topright", 2, 0)
|
||||
alphaFrame:Hide()
|
||||
alphaFrame:Hide()
|
||||
local alphaSlider = DF:NewSlider (alphaFrame, nil, "$parentAlphaSlider", "alphaSlider", 30, 220, 1, 100, 1, edit_texture:GetAlpha()*100)
|
||||
alphaSlider:SetPoint("top", alphaFrame, "top", 0, -5)
|
||||
alphaSlider:SetOrientation ("VERTICAL")
|
||||
alphaSlider.thumb:SetSize(40, 30)
|
||||
--leftSlider.backdrop = nil
|
||||
--leftSlider.fractional = true
|
||||
|
||||
|
||||
local alpha = function(button)
|
||||
|
||||
|
||||
if (ColorPickerFrame:IsShown()) then
|
||||
ColorPickerFrame:Hide()
|
||||
end
|
||||
|
||||
|
||||
if (lastButton) then
|
||||
lastButton.text:SetTextColor(unpack(originalColor))
|
||||
if (editingSide) then
|
||||
editorWindow [editingSide.."Slider"]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (not alphaFrameShown) then
|
||||
alphaFrame:Show()
|
||||
alphaSlider:SetValue(edit_texture:GetAlpha()*100)
|
||||
@@ -345,9 +340,9 @@ local CreateImageEditorFrame = function()
|
||||
button.text:SetTextColor(unpack(originalColor))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Alpha.clickfunction = alpha
|
||||
|
||||
|
||||
alphaSlider:SetHook("OnValueChange", function(_, _, value)
|
||||
edit_texture:SetAlpha(value/100)
|
||||
if (editorWindow.callback_func) then
|
||||
@@ -365,22 +360,22 @@ local CreateImageEditorFrame = function()
|
||||
resizer:SetPoint("BOTTOMRIGHT", editorWindow.widget, "BOTTOMRIGHT", 0, 0)
|
||||
resizer:EnableMouse(true)
|
||||
resizer:SetFrameLevel(editorWindow.widget:GetFrameLevel() + 2)
|
||||
|
||||
resizer:SetScript("OnMouseDown", function(self, button)
|
||||
|
||||
resizer:SetScript("OnMouseDown", function(self, button)
|
||||
editorWindow.widget:StartSizing("BOTTOMRIGHT")
|
||||
end)
|
||||
|
||||
resizer:SetScript("OnMouseUp", function(self, button)
|
||||
|
||||
resizer:SetScript("OnMouseUp", function(self, button)
|
||||
editorWindow.widget:StopMovingOrSizing()
|
||||
end)
|
||||
|
||||
|
||||
editorWindow.widget:SetScript("OnMouseDown", function()
|
||||
editorWindow.widget:StartMoving()
|
||||
end)
|
||||
editorWindow.widget:SetScript("OnMouseUp", function()
|
||||
editorWindow.widget:StopMovingOrSizing()
|
||||
end)
|
||||
|
||||
|
||||
editorWindow.widget:SetScript("OnSizeChanged", function()
|
||||
edit_texture.width = editorWindow.width
|
||||
edit_texture.height = editorWindow.height
|
||||
@@ -388,12 +383,12 @@ local CreateImageEditorFrame = function()
|
||||
rightSliderThumpTexture:SetHeight(editorWindow.height)
|
||||
topSliderThumpTexture:SetWidth(editorWindow.width)
|
||||
bottomSliderThumpTexture:SetWidth(editorWindow.width)
|
||||
|
||||
|
||||
rightCoordTexture.image:SetWidth(math.max( (editorWindow.frame:GetWidth() / 100 * math.abs(rightSlider:GetValue()-100)), 1))
|
||||
leftCoordTexture.image:SetWidth(editorWindow.frame:GetWidth()/100*leftSlider:GetValue())
|
||||
bottomCoordTexture:SetHeight(math.max( (editorWindow.frame:GetHeight() / 100 * math.abs(bottomSlider:GetValue()-100)), 1))
|
||||
topCoordTexture:SetHeight(editorWindow.frame:GetHeight()/100*topSlider:GetValue())
|
||||
|
||||
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
|
||||
@@ -289,8 +289,8 @@ DF:Mixin(SplitBarMetaFunctions, DF.ScriptHookMixin)
|
||||
end
|
||||
--font size
|
||||
local smember_textsize = function(_object, _value)
|
||||
DF:SetFontSize (_object.textleft, _value)
|
||||
return DF:SetFontSize (_object.textright, _value)
|
||||
DF:SetFontSize(_object.textleft, _value)
|
||||
return DF:SetFontSize(_object.textright, _value)
|
||||
end
|
||||
--font color
|
||||
local smember_textcolor = function(_object, _value)
|
||||
@@ -691,12 +691,12 @@ local build_statusbar = function(self)
|
||||
self.spark:SetPoint("LEFT", self, "RIGHT", -17, -1)
|
||||
|
||||
self.lefttext = self:CreateFontString("$parent_TextLeft", "OVERLAY", "GameFontHighlight")
|
||||
DF:SetFontSize (self.lefttext, 10)
|
||||
DF:SetFontSize(self.lefttext, 10)
|
||||
self.lefttext:SetJustifyH("left")
|
||||
self.lefttext:SetPoint("LEFT", self.lefticon, "RIGHT", 3, 0)
|
||||
|
||||
self.righttext = self:CreateFontString("$parent_TextRight", "OVERLAY", "GameFontHighlight")
|
||||
DF:SetFontSize (self.righttext, 10)
|
||||
DF:SetFontSize(self.righttext, 10)
|
||||
self.righttext:SetJustifyH("right")
|
||||
self.righttext:SetPoint("RIGHT", self.righticon, "LEFT", -3, 0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user