Major update
-New feature: Arena DPS Bar, can be enabled at the Broadcaster Tools section, shows a bar in 'kamehameha' style showing which team is doing more damage in the latest 3 seconds. -Revamp on the options section for Broadcaster tools. -Added 'Icon Size Offset' under Options > Bars: General, this new option allow to adjust the size of the class/spec icon shown on each bar. -Added 'Show Faction Icon' under Options > Bars: General, with this new option, you can choose to not show the faction icon, this icon is usually shown during battlegrounds. -Added 'Faction Icon Size Offset' under Options > Bars: General, new option to adjust the size of the faction icon. -Added 'Show Arena Role Icon' under Options > Bars: General, new option to hide or show the role icon of players during an arena match. -Added 'Arena Role Icon Size Offset' under Options > Bars: General, new option which allow to control the size of the arena role icon. -Added 'Level' option to Wallpapers, the wallpaper can now be placed on different levels which solves issues where the wallpaper is too low of certain configuration. -Streamer! plugin got updates, now it is more clear to pick which mode to use. -WotLK classic compatibility (Flamanis, Daniel Henry). -Fixed the title bar text not showing when using the Custom Title Bar feature. -Role detection in classic versions got improvements. -New API: Details:GetTop5Actors(attributeId), return the top 5 actors from the selected attribute. -New API: Details:GetActorByRank(attributeId, rankIndex), return an actor from the selected attribute and rankIndex. -Major cleanup and code improvements on dropdowns for library Details! Framework. -Cleanup on NickTag library. -Removed LibGroupInSpecT, LibItemUpgradeInfo and LibCompress. These libraries got replaced by OpenRaidLib and LibDeflate.
This commit is contained in:
+11
-8
@@ -1200,8 +1200,8 @@ end
|
||||
local color_button_height = 16
|
||||
local color_button_width = 16
|
||||
|
||||
local set_colorpick_color = function (button, r, g, b, a)
|
||||
a = a or 1
|
||||
local setColorPickColor = function (button, r, g, b, a)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
button.color_texture:SetVertexColor (r, g, b, a)
|
||||
end
|
||||
|
||||
@@ -1209,20 +1209,24 @@ local colorpick_cancel = function (self)
|
||||
ColorPickerFrame:Hide()
|
||||
end
|
||||
|
||||
local getColorPickColor = function(self)
|
||||
return self.color_texture:GetVertexColor()
|
||||
end
|
||||
|
||||
function DF:CreateColorPickButton (parent, name, member, callback, alpha, button_template)
|
||||
return DF:NewColorPickButton (parent, name, member, callback, alpha, button_template)
|
||||
end
|
||||
|
||||
function DF:NewColorPickButton (parent, name, member, callback, alpha, button_template)
|
||||
|
||||
--button
|
||||
local button = DF:NewButton (parent, _, name, member, color_button_width, color_button_height, pickcolor, alpha, "param2", nil, nil, nil, button_template)
|
||||
button.color_callback = callback
|
||||
button.Cancel = colorpick_cancel
|
||||
button.SetColor = set_colorpick_color
|
||||
|
||||
button.SetColor = setColorPickColor
|
||||
button.GetColor = getColorPickColor
|
||||
|
||||
button.HookList.OnColorChanged = {}
|
||||
|
||||
|
||||
if (not button_template) then
|
||||
button:InstallCustomTexture()
|
||||
button:SetBackdrop ({edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 6,
|
||||
@@ -1242,7 +1246,6 @@ function DF:NewColorPickButton (parent, name, member, callback, alpha, button_te
|
||||
img:SetPoint ("topleft", button.widget, "topleft", 0, 0)
|
||||
img:SetPoint ("bottomright", button.widget, "bottomright", 0, 0)
|
||||
img:SetDrawLayer ("background", 3)
|
||||
|
||||
|
||||
return button
|
||||
|
||||
end
|
||||
|
||||
+378
-414
File diff suppressed because it is too large
Load Diff
+189
-52
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
local dversion = 324
|
||||
local dversion = 326
|
||||
local major, minor = "DetailsFramework-1.0", dversion
|
||||
local DF, oldminor = LibStub:NewLibrary (major, minor)
|
||||
|
||||
@@ -439,6 +439,26 @@ function DF.table.reverse (t)
|
||||
return new
|
||||
end
|
||||
|
||||
function DF.table.duplicate(t1, t2)
|
||||
for key, value in pairs(t2) do
|
||||
if (key ~= "__index" and key ~= "__newindex") then
|
||||
--preserve a wowObject passing it to the new table with copying it
|
||||
if (type(value) == "table" and table.GetObjectType and table:GetObjectType()) then
|
||||
t1[key] = value
|
||||
|
||||
elseif (type (value) == "table") then
|
||||
t1[key] = t1[key] or {}
|
||||
DF.table.copy(t1[key], t2[key])
|
||||
|
||||
else
|
||||
t1[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return t1
|
||||
end
|
||||
|
||||
--> copy from table2 to table1 overwriting values
|
||||
function DF.table.copy(t1, t2)
|
||||
for key, value in pairs(t2) do
|
||||
@@ -471,6 +491,14 @@ function DF.table.copytocompress(t1, t2)
|
||||
return t1
|
||||
end
|
||||
|
||||
--add the indexes of table2 into table1
|
||||
function DF.table.append(t1, t2)
|
||||
for i = 1, #t2 do
|
||||
t1[#t1+1] = t2[i]
|
||||
end
|
||||
return t1
|
||||
end
|
||||
|
||||
--> copy values that does exist on table2 but not on table1
|
||||
function DF.table.deploy (t1, t2)
|
||||
for key, value in pairs (t2) do
|
||||
@@ -774,10 +802,16 @@ local ValidOutlines = {
|
||||
function DF:SetFontOutline (fontString, outline)
|
||||
local fonte, size = fontString:GetFont()
|
||||
if (outline) then
|
||||
if (ValidOutlines [outline]) then
|
||||
if (type(outline) == "string") then
|
||||
outline = outline:upper()
|
||||
end
|
||||
|
||||
if (ValidOutlines[outline]) then
|
||||
outline = outline
|
||||
elseif (_type (outline) == "boolean" and outline) then
|
||||
elseif (type(outline) == "boolean" and outline) then
|
||||
outline = "OUTLINE"
|
||||
elseif (type(outline) == "boolean" and not outline) then
|
||||
outline = "NONE"
|
||||
elseif (outline == 1) then
|
||||
outline = "OUTLINE"
|
||||
elseif (outline == 2) then
|
||||
@@ -850,6 +884,21 @@ function DF:CleanTruncateUTF8String(text)
|
||||
return text
|
||||
end
|
||||
|
||||
--DF:TruncateNumber(number, fractionDigits): truncate the amount of numbers used to show fraction.
|
||||
function DF:TruncateNumber(number, fractionDigits)
|
||||
fractionDigits = fractionDigits or 2
|
||||
--local truncatedNumber = format("%." .. fractionDigits .. "f", number) --4x slower than:
|
||||
--http://lua-users.org/wiki/SimpleRound
|
||||
local mult = 10 ^ fractionDigits
|
||||
if (number >= 0) then
|
||||
truncatedNumber = floor(number * mult + 0.5) / mult
|
||||
else
|
||||
truncatedNumber = ceil(number * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
return truncatedNumber
|
||||
end
|
||||
|
||||
function DF:Msg (msg, ...)
|
||||
print ("|cFFFFFFAA" .. (self.__name or "FW Msg:") .. "|r ", msg, ...)
|
||||
end
|
||||
@@ -1151,7 +1200,37 @@ end
|
||||
|
||||
IsColorTable = true,
|
||||
}
|
||||
|
||||
|
||||
--convert a any format of color to any other format of color
|
||||
function DF:FormatColor(newFormat, r, g, b, a, decimalsAmount)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
decimalsAmount = decimalsAmount or 4
|
||||
|
||||
r = DF:TruncateNumber(r, decimalsAmount)
|
||||
g = DF:TruncateNumber(g, decimalsAmount)
|
||||
b = DF:TruncateNumber(b, decimalsAmount)
|
||||
a = DF:TruncateNumber(a, decimalsAmount)
|
||||
|
||||
if (newFormat == "commastring") then
|
||||
return r .. ", " .. g .. ", " .. b .. ", " .. a
|
||||
|
||||
elseif (newFormat == "tablestring") then
|
||||
return "{" .. r .. ", " .. g .. ", " .. b .. ", " .. a .. "}"
|
||||
|
||||
elseif (newFormat == "table") then
|
||||
return {r, g, b, a}
|
||||
|
||||
elseif (newFormat == "tablemembers") then
|
||||
return {["r"] = r, ["g"] = g, ["b"] = b, ["a"] = 1}
|
||||
|
||||
elseif (newFormat == "numbers") then
|
||||
return r, g, b, a
|
||||
|
||||
elseif (newFormat == "hex") then
|
||||
return format("%.2x%.2x%.2x%.2x", a * 255, r * 255, g * 255, b * 255)
|
||||
end
|
||||
end
|
||||
|
||||
function DF:CreateColorTable (r, g, b, a)
|
||||
local t = {
|
||||
r = r or 1,
|
||||
@@ -1167,53 +1246,69 @@ end
|
||||
return DF.alias_text_colors [color]
|
||||
end
|
||||
|
||||
local tn = tonumber
|
||||
function DF:ParseColors (_arg1, _arg2, _arg3, _arg4)
|
||||
if (_type (_arg1) == "table") then
|
||||
if (_arg1.IsColorTable) then
|
||||
return _arg1:GetColor()
|
||||
|
||||
elseif (not _arg1[1] and _arg1.r) then
|
||||
_arg1, _arg2, _arg3, _arg4 = _arg1.r, _arg1.g, _arg1.b, _arg1.a
|
||||
|
||||
function DF:ParseColors (red, green, blue, alpha)
|
||||
local firstParameter = red
|
||||
|
||||
--the first value passed is a table?
|
||||
if (type(firstParameter) == "table") then
|
||||
local colorTable = red
|
||||
|
||||
if (colorTable.IsColorTable) then
|
||||
--using colorTable mixin
|
||||
return colorTable:GetColor()
|
||||
|
||||
elseif (not colorTable[1] and colorTable.r) then
|
||||
--{["r"] = 1, ["g"] = 1, ["b"] = 1}
|
||||
red, green, blue, alpha = colorTable.r, colorTable.g, colorTable.b, colorTable.a
|
||||
|
||||
else
|
||||
_arg1, _arg2, _arg3, _arg4 = _unpack (_arg1)
|
||||
--{1, .7, .2, 1}
|
||||
red, green, blue, alpha = unpack(colorTable)
|
||||
end
|
||||
|
||||
elseif (_type (_arg1) == "string") then
|
||||
|
||||
if (string.find (_arg1, "#")) then
|
||||
_arg1 = _arg1:gsub ("#","")
|
||||
if (string.len (_arg1) == 8) then --alpha
|
||||
_arg1, _arg2, _arg3, _arg4 = tn ("0x" .. _arg1:sub (3, 4))/255, tn ("0x" .. _arg1:sub (5, 6))/255, tn ("0x" .. _arg1:sub (7, 8))/255, tn ("0x" .. _arg1:sub (1, 2))/255
|
||||
|
||||
--the first value passed is a string?
|
||||
elseif (type(firstParameter) == "string") then
|
||||
local colorString = red
|
||||
--hexadecimal
|
||||
if (string.find(colorString, "#")) then
|
||||
colorString = colorString:gsub("#","")
|
||||
if (string.len(colorString) == 8) then --with alpha
|
||||
red, green, blue, alpha = tonumber("0x" .. colorString:sub(3, 4))/255, tonumber("0x" .. colorString:sub(5, 6))/255, tonumber("0x" .. colorString:sub(7, 8))/255, tonumber("0x" .. colorString:sub(1, 2))/255
|
||||
else
|
||||
_arg1, _arg2, _arg3, _arg4 = tn ("0x" .. _arg1:sub (1, 2))/255, tn ("0x" .. _arg1:sub (3, 4))/255, tn ("0x" .. _arg1:sub (5, 6))/255, 1
|
||||
red, green, blue, alpha = tonumber("0x" .. colorString:sub(1, 2))/255, tonumber("0x" .. colorString:sub(3, 4))/255, tonumber("0x" .. colorString:sub(5, 6))/255, 1
|
||||
end
|
||||
|
||||
else
|
||||
local color = DF.alias_text_colors [_arg1]
|
||||
if (color) then
|
||||
_arg1, _arg2, _arg3, _arg4 = _unpack (color)
|
||||
--name of the color
|
||||
local colorTable = DF.alias_text_colors[colorString]
|
||||
if (colorTable) then
|
||||
red, green, blue, alpha = unpack(colorTable)
|
||||
|
||||
--string with number separated by comma
|
||||
elseif (colorString:find(",")) then
|
||||
local r, g, b, a = strsplit(",", colorString)
|
||||
red, green, blue, alpha = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
|
||||
|
||||
else
|
||||
_arg1, _arg2, _arg3, _arg4 = _unpack (DF.alias_text_colors.none)
|
||||
--no color found within the string, return default color
|
||||
red, green, blue, alpha = unpack(DF.alias_text_colors.none)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (not _arg1) then
|
||||
_arg1 = 1
|
||||
|
||||
if (not red or type(red) ~= "number") then
|
||||
red = 1
|
||||
end
|
||||
if (not _arg2) then
|
||||
_arg2 = 1
|
||||
if (not green) or type(green) ~= "number" then
|
||||
green = 1
|
||||
end
|
||||
if (not _arg3) then
|
||||
_arg3 = 1
|
||||
if (not blue or type(blue) ~= "number") then
|
||||
blue = 1
|
||||
end
|
||||
if (not _arg4) then
|
||||
_arg4 = 1
|
||||
if (not alpha or type(alpha) ~= "number") then
|
||||
alpha = 1
|
||||
end
|
||||
|
||||
return _arg1, _arg2, _arg3, _arg4
|
||||
|
||||
return red, green, blue, alpha
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -2391,7 +2486,7 @@ function DF:GetBestFontForLanguage (language, western, cyrillic, china, korean,
|
||||
end
|
||||
|
||||
if (language == "enUS" or language == "deDE" or language == "esES" or language == "esMX" or language == "frFR" or language == "itIT" or language == "ptBR") then
|
||||
return western or "Accidental Presidency"
|
||||
return western or "Friz Quadrata TT"
|
||||
|
||||
elseif (language == "ruRU") then
|
||||
return cyrillic or "Arial Narrow"
|
||||
@@ -3152,6 +3247,7 @@ function DF:CreateGlowOverlay (parent, antsColor, glowColor)
|
||||
glowFrame.GlowColor = {r, g, b, a}
|
||||
|
||||
glowFrame.outerGlow:SetScale (1.2)
|
||||
glowFrame:EnableMouse(false)
|
||||
return glowFrame
|
||||
end
|
||||
|
||||
@@ -3693,6 +3789,10 @@ function DF:GetCurrentSpec()
|
||||
end
|
||||
end
|
||||
|
||||
function DF:GetCurrentSpecId()
|
||||
return DF:GetCurrentSpec()
|
||||
end
|
||||
|
||||
local specs_per_class = {
|
||||
["DEMONHUNTER"] = {577, 581},
|
||||
["DEATHKNIGHT"] = {250, 251, 252},
|
||||
@@ -3733,18 +3833,21 @@ function DF:QuickDispatch (func, ...)
|
||||
return true
|
||||
end
|
||||
|
||||
function DF:Dispatch (func, ...)
|
||||
function DF:Dispatch(func, ...)
|
||||
if (type (func) ~= "function") then
|
||||
return dispatch_error (_, "Dispatch required a function.")
|
||||
return dispatch_error (_, "DF:Dispatch expect a function as parameter 1.")
|
||||
end
|
||||
|
||||
local okay, result1, result2, result3, result4 = xpcall (func, geterrorhandler(), ...)
|
||||
|
||||
local dispatchResult = {xpcall (func, geterrorhandler(), ...)}
|
||||
local okay = dispatchResult[1]
|
||||
|
||||
if (not okay) then
|
||||
return nil
|
||||
end
|
||||
|
||||
return result1, result2, result3, result4
|
||||
|
||||
tremove(dispatchResult, 1)
|
||||
|
||||
return unpack(dispatchResult)
|
||||
end
|
||||
|
||||
--[=[
|
||||
@@ -3900,7 +4003,7 @@ end
|
||||
|
||||
--> store and return a list of character races, always return the non-localized value
|
||||
DF.RaceCache = {}
|
||||
function DF:GetCharacterRaceList (fullList)
|
||||
function DF:GetCharacterRaceList()
|
||||
if (next (DF.RaceCache)) then
|
||||
return DF.RaceCache
|
||||
end
|
||||
@@ -3908,13 +4011,13 @@ function DF:GetCharacterRaceList (fullList)
|
||||
for i = 1, 100 do
|
||||
local raceInfo = C_CreatureInfo.GetRaceInfo (i)
|
||||
if (raceInfo and DF.RaceList [raceInfo.raceID]) then
|
||||
tinsert (DF.RaceCache, {Name = raceInfo.raceName, FileString = raceInfo.clientFileString})
|
||||
tinsert (DF.RaceCache, {Name = raceInfo.raceName, FileString = raceInfo.clientFileString, ID = raceInfo.raceID})
|
||||
end
|
||||
|
||||
if IS_WOW_PROJECT_MAINLINE then
|
||||
local alliedRaceInfo = C_AlliedRaces.GetRaceInfoByID (i)
|
||||
if (alliedRaceInfo and DF.AlliedRaceList [alliedRaceInfo.raceID]) then
|
||||
tinsert (DF.RaceCache, {Name = alliedRaceInfo.maleName, FileString = alliedRaceInfo.raceFileString})
|
||||
tinsert (DF.RaceCache, {Name = alliedRaceInfo.maleName, FileString = alliedRaceInfo.raceFileString, ID = alliedRaceInfo.raceID})
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4046,6 +4149,11 @@ function DF:AddRoleIconToText(text, role, size)
|
||||
return text
|
||||
end
|
||||
|
||||
function DF:GetRoleTCoordsAndTexture(roleID)
|
||||
local texture, l, r, t, b = DF:GetRoleIconAndCoords(roleID)
|
||||
return l, r, t, b, texture
|
||||
end
|
||||
|
||||
-- TODO: maybe make this auto-generaded some day?...
|
||||
DF.CLEncounterID = {
|
||||
{ID = 2423, Name = "The Tarragrue"},
|
||||
@@ -4243,6 +4351,10 @@ DF.BattlegroundSizes = {
|
||||
[1803] = 10, --Seething Shore
|
||||
}
|
||||
|
||||
function DF:GetBattlegroundSize(instanceInfoMapId)
|
||||
return DF.BattlegroundSizes[instanceInfoMapId]
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--> execute range
|
||||
|
||||
@@ -4340,6 +4452,10 @@ function GetWorldDeltaSeconds()
|
||||
return deltaTimeFrame.deltaTime
|
||||
end
|
||||
|
||||
function DF:GetWorldDeltaSeconds()
|
||||
return deltaTimeFrame.deltaTime
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--> build the global script channel for scripts communication
|
||||
--send and retrieve data sent by othe users in scripts
|
||||
@@ -4368,6 +4484,7 @@ end
|
||||
if (Ambiguate (sourceName, "none") == commSource) then
|
||||
local func = DF.RegisteredScriptsComm [ID]
|
||||
if (func) then
|
||||
DF:MakeFunctionSecure(func)
|
||||
DF:Dispatch (func, commSource, select (5, unpack (data))) --this use xpcall
|
||||
end
|
||||
end
|
||||
@@ -4449,7 +4566,7 @@ do
|
||||
if (object) then
|
||||
tinsert(self.inUse, object)
|
||||
if (self.onAcquire) then
|
||||
local result, errortext = pcall(self.onAcquire, object)
|
||||
DF:QuickDispatch(self.onAcquire, object)
|
||||
end
|
||||
return object, false
|
||||
else
|
||||
@@ -4458,7 +4575,7 @@ do
|
||||
if (newObject) then
|
||||
tinsert(self.inUse, newObject)
|
||||
if (self.onAcquire) then
|
||||
local result, errortext = pcall(self.onAcquire, object)
|
||||
DF:QuickDispatch(self.onAcquire, object)
|
||||
end
|
||||
return newObject, true
|
||||
end
|
||||
@@ -4474,6 +4591,10 @@ do
|
||||
if (self.inUse[i] == object) then
|
||||
tremove(self.inUse, i)
|
||||
tinsert(self.notUse, object)
|
||||
|
||||
if (self.onRelease) then
|
||||
DF:QuickDispatch(self.onRelease, object)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -4485,7 +4606,7 @@ do
|
||||
tinsert(self.notUse, object)
|
||||
|
||||
if (self.onReset) then
|
||||
local result, errortext = pcall(self.onReset, object)
|
||||
DF:QuickDispatch(self.onReset, object)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4519,12 +4640,24 @@ do
|
||||
Hide = hide,
|
||||
Show = show,
|
||||
GetAmount = getamount,
|
||||
|
||||
SetCallbackOnRelease = function(self, func)
|
||||
self.onRelease = func
|
||||
end,
|
||||
|
||||
SetOnReset = function(self, func)
|
||||
self.onReset = func
|
||||
end,
|
||||
SetCallbackOnReleaseAll = function(self, func)
|
||||
self.onReset = func
|
||||
end,
|
||||
|
||||
SetOnAcquire = function(self, func)
|
||||
self.onAcquire = func
|
||||
end,
|
||||
SetCallbackOnGet = function(self, func)
|
||||
self.onAcquire = func
|
||||
end,
|
||||
}
|
||||
|
||||
function DF:CreatePool(func, ...)
|
||||
@@ -4573,7 +4706,7 @@ end
|
||||
--block run code inside code
|
||||
["RunScript"] = true,
|
||||
["securecall"] = true,
|
||||
["getfenv"] = true,
|
||||
["setfenv"] = true,
|
||||
["getfenv"] = true,
|
||||
["loadstring"] = true,
|
||||
["pcall"] = true,
|
||||
@@ -4662,6 +4795,10 @@ end
|
||||
_G.setfenv(func, newEnvironment)
|
||||
end
|
||||
|
||||
function DF:MakeFunctionSecure(func)
|
||||
return DF:SetEnvironment(func)
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<Script file ="DFPixelUtil.lua"/>
|
||||
<Script file="fw.lua"/>
|
||||
<Script file="mixins.lua"/>
|
||||
<Script file="addon.lua"/>
|
||||
<Script file="colors.lua"/>
|
||||
<Script file="help.lua"/>
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
|
||||
--mixin for options functions
|
||||
DF.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
|
||||
DF: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 {}
|
||||
DF.table.deploy (self.options, userOptions or {})
|
||||
DF.table.deploy (self.options, defaultOptions or {})
|
||||
end
|
||||
}
|
||||
|
||||
--payload mixin
|
||||
DF.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 = DF.table.duplicate({}, self.payload)
|
||||
return duplicatedPayload
|
||||
end,
|
||||
}
|
||||
+7
-41
@@ -63,44 +63,6 @@ end
|
||||
|
||||
local PanelMetaFunctions = _G[DF.GlobalWidgetControlNames ["panel"]]
|
||||
|
||||
--> mixin for options functions
|
||||
DF.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
|
||||
DF: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 {}
|
||||
DF.table.deploy (self.options, userOptions or {})
|
||||
DF.table.deploy (self.options, defaultOptions or {})
|
||||
end
|
||||
}
|
||||
|
||||
--> default options for the frame layout
|
||||
local default_framelayout_options = {
|
||||
amount_per_line = 4,
|
||||
@@ -2144,6 +2106,10 @@ function DF:CreateSimplePanel (parent, w, h, title, name, panel_options, db)
|
||||
|
||||
f.Title:SetPoint ("center", title_bar, "center")
|
||||
f.Close:SetPoint ("right", title_bar, "right", -2, 0)
|
||||
|
||||
if (panel_options.NoCloseButton) then
|
||||
f.Close:Hide()
|
||||
end
|
||||
|
||||
f:SetScript ("OnMouseDown", simple_panel_mouse_down)
|
||||
f:SetScript ("OnMouseUp", simple_panel_mouse_up)
|
||||
@@ -8349,7 +8315,7 @@ DF.CastFrameFunctions = {
|
||||
end,
|
||||
|
||||
HasScheduledHide = function (self)
|
||||
return self.scheduledHideTime and not self.scheduledHideTime._cancelled
|
||||
return self.scheduledHideTime and not self.scheduledHideTime:IsCancelled()
|
||||
end,
|
||||
|
||||
CancelScheduleToHide = function (self)
|
||||
@@ -8361,7 +8327,7 @@ DF.CastFrameFunctions = {
|
||||
--> after an interrupt, do not immediately hide the cast bar, let it up for short amount of time to give feedback to the player
|
||||
ScheduleToHide = function (self, delay)
|
||||
if (not delay) then
|
||||
if (self.scheduledHideTime and not self.scheduledHideTime._cancelled) then
|
||||
if (self.scheduledHideTime and not self.scheduledHideTime:IsCancelled()) then
|
||||
self.scheduledHideTime:Cancel()
|
||||
end
|
||||
|
||||
@@ -8370,7 +8336,7 @@ DF.CastFrameFunctions = {
|
||||
end
|
||||
|
||||
--> already have a scheduled timer?
|
||||
if (self.scheduledHideTime and not self.scheduledHideTime._cancelled) then
|
||||
if (self.scheduledHideTime and not self.scheduledHideTime:IsCancelled()) then
|
||||
self.scheduledHideTime:Cancel()
|
||||
end
|
||||
|
||||
|
||||
@@ -1285,3 +1285,195 @@ function DF:NewSlider (parent, container, name, member, w, h, min, max, step, de
|
||||
return SliderObject, with_label
|
||||
|
||||
end
|
||||
|
||||
DF.AdjustmentSliderOptions = {
|
||||
width = 120,
|
||||
height = 20,
|
||||
speed = 20, --speed is how many pixels the mouse has moved
|
||||
}
|
||||
|
||||
DF.AdjustmentSliderFunctions = {
|
||||
SetCallback = function(self, func)
|
||||
self.callback = func
|
||||
end,
|
||||
|
||||
SetPayload = function(self, ...)
|
||||
self.payload = {...}
|
||||
end,
|
||||
|
||||
RunCallback = function(adjustmentSlider, valueX, valueY, isLiteral)
|
||||
local result, errorText = pcall(adjustmentSlider.callback, adjustmentSlider, valueX, valueY, isLiteral, adjustmentSlider:DumpPayload())
|
||||
if (not result) then
|
||||
DF:Msg("AdjustmentSlider callback Error:", errorText)
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
--calculate if the mouse has moved and call a callback
|
||||
PressingOnUpdate = function(adjustmentSlider, deltaTime)
|
||||
if (GetTime() > adjustmentSlider.NextTick) then
|
||||
--get currentr mouse position
|
||||
local mouseX, mouseY = GetCursorPosition()
|
||||
local verticalValue
|
||||
local horizontalValue
|
||||
|
||||
--find distance
|
||||
local xDelta = adjustmentSlider.MouseX - mouseX --moving the mouse to right or up result in a negative delta
|
||||
local yDelta = adjustmentSlider.MouseY - mouseY
|
||||
|
||||
if (adjustmentSlider.buttonPressed ~= "center") then
|
||||
if (adjustmentSlider.buttonPressedTime+0.5 < GetTime()) then
|
||||
if (adjustmentSlider.buttonPressed == "left") then
|
||||
DF.AdjustmentSliderFunctions.RunCallback(adjustmentSlider, -1, 0, true)
|
||||
elseif (adjustmentSlider.buttonPressed == "right") then
|
||||
DF.AdjustmentSliderFunctions.RunCallback(adjustmentSlider, 1, 0, true)
|
||||
end
|
||||
end
|
||||
|
||||
elseif (xDelta ~= 0 or yDelta ~= 0) then
|
||||
if (adjustmentSlider.buttonPressed == "center") then
|
||||
--invert axis as left is positive and right is negative in the deltas
|
||||
xDelta = xDelta * -1
|
||||
yDelta = yDelta * -1
|
||||
|
||||
horizontalValue = DF:MapRangeClamped(-20, 20, -1, 1, xDelta)
|
||||
verticalValue = DF:MapRangeClamped(-20, 20, -1, 1, yDelta)
|
||||
end
|
||||
|
||||
DF.AdjustmentSliderFunctions.RunCallback(adjustmentSlider, horizontalValue, verticalValue, false)
|
||||
|
||||
adjustmentSlider.MouseX = mouseX
|
||||
adjustmentSlider.MouseY = mouseY
|
||||
end
|
||||
|
||||
adjustmentSlider.NextTick = GetTime() + 0.05
|
||||
end
|
||||
end,
|
||||
|
||||
--button can be the left or right button
|
||||
OnButtonDownkHook = function(button)
|
||||
button = button.MyObject
|
||||
|
||||
--change the icon
|
||||
if (button.direction == "left") then
|
||||
button:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-PrevPage-Down]])
|
||||
elseif (button.direction == "right") then
|
||||
button:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-NextPage-Down]])
|
||||
end
|
||||
|
||||
local adjustmentSlider = button:GetParent()
|
||||
adjustmentSlider.NextTick = GetTime() + 0.05
|
||||
|
||||
--save where the mouse is on the moment of the click
|
||||
local mouseX, mouseY = GetCursorPosition()
|
||||
adjustmentSlider.MouseX = mouseX
|
||||
adjustmentSlider.MouseY = mouseY
|
||||
|
||||
adjustmentSlider.buttonPressed = button.direction
|
||||
|
||||
--start monitoring the mouse moviment
|
||||
adjustmentSlider.buttonPressedTime = GetTime()
|
||||
adjustmentSlider:SetScript("OnUpdate", DF.AdjustmentSliderFunctions.PressingOnUpdate)
|
||||
end,
|
||||
|
||||
--button can be the left or right button
|
||||
OnButtonUpHook = function(button)
|
||||
button = button.MyObject
|
||||
|
||||
--change the icon
|
||||
if (button.direction == "left") then
|
||||
button:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-PrevPage-Up]])
|
||||
elseif (button.direction == "right") then
|
||||
button:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-NextPage-Up]])
|
||||
end
|
||||
|
||||
local adjustmentSlider = button:GetParent()
|
||||
|
||||
--check if the mouse did not moved at all, if not send a callback with a value of 1
|
||||
local mouseX, mouseY = GetCursorPosition()
|
||||
if (mouseX == adjustmentSlider.MouseX and mouseY == adjustmentSlider.MouseY and adjustmentSlider.buttonPressedTime+0.5 > GetTime()) then
|
||||
if (button.direction == "left") then
|
||||
DF.AdjustmentSliderFunctions.RunCallback(adjustmentSlider, -1, 0, true)
|
||||
elseif (button.direction == "right") then
|
||||
DF.AdjustmentSliderFunctions.RunCallback(adjustmentSlider, 1, 0, true)
|
||||
end
|
||||
end
|
||||
|
||||
adjustmentSlider:SetScript("OnUpdate", nil)
|
||||
end,
|
||||
|
||||
Disable = function(adjustmentSlider)
|
||||
adjustmentSlider.leftButton:Disable()
|
||||
adjustmentSlider.rightButton:Disable()
|
||||
adjustmentSlider.centerButton:Disable()
|
||||
end,
|
||||
|
||||
Enable = function(adjustmentSlider)
|
||||
adjustmentSlider.leftButton:Enable()
|
||||
adjustmentSlider.rightButton:Enable()
|
||||
adjustmentSlider.centerButton:Enable()
|
||||
end,
|
||||
}
|
||||
|
||||
local createAdjustmentSliderFrames = function(parent, options, name)
|
||||
--frame it self
|
||||
local adjustmentSlider = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
|
||||
DF:Mixin(adjustmentSlider, DF.OptionsFunctions)
|
||||
DF:Mixin(adjustmentSlider, DF.AdjustmentSliderFunctions)
|
||||
DF:Mixin(adjustmentSlider, DF.PayloadMixin)
|
||||
|
||||
adjustmentSlider:BuildOptionsTable(DF.AdjustmentSliderOptions, options)
|
||||
|
||||
adjustmentSlider:SetSize(adjustmentSlider.options.width, adjustmentSlider.options.height)
|
||||
|
||||
--two buttons
|
||||
local leftButton = DF:CreateButton(adjustmentSlider, function()end, 20, 20, "", "left", -1, nil, nil, name .. "LeftButton")
|
||||
local rightButton = DF:CreateButton(adjustmentSlider, function()end, 20, 20, "", "right", 1, nil, nil, name .. "RightButton")
|
||||
|
||||
leftButton:SetHook("OnMouseDown", DF.AdjustmentSliderFunctions.OnButtonDownkHook)
|
||||
rightButton:SetHook("OnMouseDown", DF.AdjustmentSliderFunctions.OnButtonDownkHook)
|
||||
leftButton:SetHook("OnMouseUp", DF.AdjustmentSliderFunctions.OnButtonUpHook)
|
||||
rightButton:SetHook("OnMouseUp", DF.AdjustmentSliderFunctions.OnButtonUpHook)
|
||||
|
||||
leftButton:SetPoint("left", adjustmentSlider, "left", 0, 0)
|
||||
rightButton:SetPoint("right", adjustmentSlider, "right", 0, 0)
|
||||
leftButton:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-PrevPage-Up]])
|
||||
rightButton:SetIcon([[Interface\BUTTONS\UI-SpellbookIcon-NextPage-Up]])
|
||||
leftButton.direction = "left"
|
||||
rightButton.direction = "right"
|
||||
|
||||
--center button
|
||||
local centerButton = DF:CreateButton(adjustmentSlider, function()end, 20, 20, "", "center", 0, nil, nil, name .. "CenterButton")
|
||||
centerButton:SetPoint("center", adjustmentSlider, "center", 0, 0)
|
||||
centerButton:SetIcon([[Interface\BUTTONS\YellowOrange64_Radial]])
|
||||
centerButton.direction = "center"
|
||||
centerButton:SetHook("OnMouseDown", DF.AdjustmentSliderFunctions.OnButtonDownkHook)
|
||||
centerButton:SetHook("OnMouseUp", DF.AdjustmentSliderFunctions.OnButtonUpHook)
|
||||
|
||||
adjustmentSlider.leftButton = leftButton
|
||||
adjustmentSlider.rightButton = rightButton
|
||||
adjustmentSlider.centerButton = centerButton
|
||||
|
||||
return adjustmentSlider
|
||||
end
|
||||
|
||||
--creates a slider with left and right buttons and a center button, on click the hold, mouse moviments adjust the value and trigger a callback with a normallized x and y values of the mouse movement
|
||||
--@parent: who is the parent of this frame
|
||||
--@callback: run when there's a change in any of the two axis
|
||||
--@options: a table containing options for the frame, see /dump DetailsFramework.AdjustmentSliderOptions
|
||||
--@name: the name of the frame, if none a generic name is created
|
||||
function DF:CreateAdjustmentSlider(parent, callback, options, name, ...)
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkAdjustmentSlider" .. DF.SliderCounter
|
||||
DF.SliderCounter = DF.SliderCounter + 1
|
||||
|
||||
elseif (not parent) then
|
||||
return error("Details! FrameWork: parent not found.", 2)
|
||||
end
|
||||
|
||||
local ASFrame = createAdjustmentSliderFrames(parent, options, name)
|
||||
ASFrame:SetPayload(...)
|
||||
ASFrame.callback = callback
|
||||
return ASFrame
|
||||
end
|
||||
|
||||
+17
-3
@@ -341,7 +341,11 @@ DF.TextEntryCounter = DF.TextEntryCounter or 1
|
||||
self.func = func
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function TextEntryMetaFunctions:IgnoreNextCallback()
|
||||
self.ignoreNextCallback = true
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--> scripts and hooks
|
||||
|
||||
@@ -406,7 +410,12 @@ DF.TextEntryCounter = DF.TextEntryCounter or 1
|
||||
|
||||
local OnEnterPressed = function (textentry, byScript)
|
||||
local capsule = textentry.MyObject
|
||||
|
||||
|
||||
if (capsule.ignoreNextCallback) then
|
||||
DF.Schedules.RunNextTick(function() capsule.ignoreNextCallback = nil end)
|
||||
return
|
||||
end
|
||||
|
||||
local kill = capsule:RunHooksForWidget ("OnEnterPressed", textentry, capsule, capsule.text)
|
||||
if (kill) then
|
||||
return
|
||||
@@ -457,7 +466,12 @@ DF.TextEntryCounter = DF.TextEntryCounter or 1
|
||||
local OnEditFocusLost = function (textentry)
|
||||
|
||||
local capsule = textentry.MyObject
|
||||
|
||||
|
||||
if (capsule.ignoreNextCallback) then
|
||||
DF.Schedules.RunNextTick(function() capsule.ignoreNextCallback = nil end)
|
||||
return
|
||||
end
|
||||
|
||||
if (textentry:IsShown()) then
|
||||
|
||||
local kill = capsule:RunHooksForWidget ("OnEditFocusLost", textentry, capsule, capsule.text)
|
||||
|
||||
Reference in New Issue
Block a user