framework update
This commit is contained in:
+119
-43
@@ -211,27 +211,7 @@ detailsFramework:Mixin(ButtonMetaFunctions, detailsFramework.ScriptHookMixin)
|
||||
|
||||
--texture
|
||||
local smember_texture = function(object, value)
|
||||
if (type(value) == "table") then
|
||||
local value1, value2, value3, value4 = unpack(value)
|
||||
if (value1) then
|
||||
object.button:SetNormalTexture(value1)
|
||||
end
|
||||
if (value2) then
|
||||
object.button:SetHighlightTexture(value2, "ADD")
|
||||
end
|
||||
if (value3) then
|
||||
object.button:SetPushedTexture(value3)
|
||||
end
|
||||
if (value4) then
|
||||
object.button:SetDisabledTexture(value4)
|
||||
end
|
||||
else
|
||||
object.button:SetNormalTexture(value)
|
||||
object.button:SetHighlightTexture(value, "ADD")
|
||||
object.button:SetPushedTexture(value)
|
||||
object.button:SetDisabledTexture(value)
|
||||
end
|
||||
return
|
||||
return detailsFramework:SetButtonTexture(object, value, 0, 1, 0, 1)
|
||||
end
|
||||
|
||||
--locked
|
||||
@@ -1120,7 +1100,14 @@ end
|
||||
return colorPickButton
|
||||
end
|
||||
|
||||
function detailsFramework:SetRegularButtonTexture(button, texture, left, right, top, bottom)
|
||||
---set the texture of all 4 textures of a button to the same texture
|
||||
---@param button button
|
||||
---@param texture textureid|texturepath
|
||||
---@param left coordleft|table|nil
|
||||
---@param right coordright|nil
|
||||
---@param top coordtop|nil
|
||||
---@param bottom coordbottom|nil
|
||||
function detailsFramework:SetButtonTexture(button, texture, left, right, top, bottom)
|
||||
if (type(left) == "table") then
|
||||
left, right, top, bottom = unpack(left)
|
||||
end
|
||||
@@ -1132,23 +1119,54 @@ end
|
||||
local atlas
|
||||
if (type(texture) == "string") then
|
||||
atlas = C_Texture.GetAtlasInfo(texture)
|
||||
end
|
||||
end
|
||||
|
||||
local normalTexture = button:GetNormalTexture()
|
||||
local pushedTexture = button:GetPushedTexture()
|
||||
local highlightTexture = button:GetHightlightTexture()
|
||||
local disabledTexture = button:GetDisabledTexture()
|
||||
local normalTexture = button:GetNormalTexture()
|
||||
local pushedTexture = button:GetPushedTexture()
|
||||
local highlightTexture = button:GetHightlightTexture()
|
||||
local disabledTexture = button:GetDisabledTexture()
|
||||
|
||||
if (type(texture) == "table") then
|
||||
local normalTexturePath, pushedTexturePath, highlightTexturePath, disabledTexturePath = unpack(texture)
|
||||
---@cast right number
|
||||
---@cast top number
|
||||
---@cast bottom number
|
||||
|
||||
if (normalTexturePath) then
|
||||
normalTexture:SetTexture(normalTexturePath)
|
||||
normalTexture:SetTexCoord(left, right, top, bottom)
|
||||
end
|
||||
|
||||
if (pushedTexturePath) then
|
||||
pushedTexture:SetTexture(pushedTexturePath)
|
||||
pushedTexture:SetTexCoord(left, right, top, bottom)
|
||||
end
|
||||
|
||||
if (highlightTexturePath) then
|
||||
highlightTexture:SetTexture(highlightTexturePath)
|
||||
highlightTexture:SetTexCoord(left, right, top, bottom)
|
||||
end
|
||||
|
||||
if (disabledTexturePath) then
|
||||
disabledTexture:SetTexture(disabledTexturePath)
|
||||
disabledTexture:SetTexCoord(left, right, top, bottom)
|
||||
end
|
||||
|
||||
elseif (atlas) then
|
||||
normalTexture:SetAtlas(atlas)
|
||||
pushedTexture:SetAtlas(atlas)
|
||||
highlightTexture:SetAtlas(atlas)
|
||||
disabledTexture:SetAtlas(atlas)
|
||||
|
||||
if (atlas) then
|
||||
normalTexture:SetAtlas(texture)
|
||||
pushedTexture:SetAtlas(texture)
|
||||
highlightTexture:SetAtlas(texture)
|
||||
disabledTexture:SetAtlas(texture)
|
||||
else
|
||||
normalTexture:SetTexture(texture)
|
||||
pushedTexture:SetTexture(texture)
|
||||
highlightTexture:SetTexture(texture)
|
||||
disabledTexture:SetTexture(texture)
|
||||
|
||||
---@cast right number
|
||||
---@cast top number
|
||||
---@cast bottom number
|
||||
normalTexture:SetTexCoord(left, right, top, bottom)
|
||||
pushedTexture:SetTexCoord(left, right, top, bottom)
|
||||
highlightTexture:SetTexCoord(left, right, top, bottom)
|
||||
@@ -1156,17 +1174,23 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
function detailsFramework:SetRegularButtonVertexColor(button, ...)
|
||||
local r, g, b, a = detailsFramework:ParseColor(...)
|
||||
---set the vertex color of all 4 textures of a button to the same color
|
||||
---@param button button
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
function detailsFramework:SetButtonVertexColor(button, red, green, blue, alpha)
|
||||
red, green, blue, alpha = detailsFramework:ParseColor(red, green, blue, alpha)
|
||||
local normalTexture = button:GetNormalTexture()
|
||||
local pushedTexture = button:GetPushedTexture()
|
||||
local highlightTexture = button:GetHightlightTexture()
|
||||
local disabledTexture = button:GetDisabledTexture()
|
||||
|
||||
normalTexture:SetVertexColor(r, g, b, a)
|
||||
pushedTexture:SetVertexColor(r, g, b, a)
|
||||
highlightTexture:SetVertexColor(r, g, b, a)
|
||||
disabledTexture:SetVertexColor(r, g, b, a)
|
||||
normalTexture:SetVertexColor(red, green, blue, alpha)
|
||||
pushedTexture:SetVertexColor(red, green, blue, alpha)
|
||||
highlightTexture:SetVertexColor(red, green, blue, alpha)
|
||||
disabledTexture:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
|
||||
@@ -1187,10 +1211,12 @@ end
|
||||
---@field rightTextureSelectedName string
|
||||
---@field middleTextureSelectedName string
|
||||
---@field bIsSelected boolean
|
||||
---@field SetText fun(self: df_tabbutton, text: string)
|
||||
---@field SetSelected fun(self: df_tabbutton, selected: boolean)
|
||||
---@field IsSelected fun(self: df_tabbutton): boolean
|
||||
---@field Reset fun(self: df_tabbutton)
|
||||
---@field SetText fun(self: df_tabbutton, text: string) --set the tab text
|
||||
---@field SetSelected fun(self: df_tabbutton, selected: boolean) --highlight the tab textures to indicate the tab is selected
|
||||
---@field SetShowCloseButton fun(self: df_tabbutton, show: boolean) --set if the close button can be shown or not
|
||||
---@field GetFontString fun(self: df_tabbutton) : fontstring --get the fontstring used to display the tab text
|
||||
---@field IsSelected fun(self: df_tabbutton): boolean --get a boolean representing if the tab is selected
|
||||
---@field Reset fun(self: df_tabbutton) --set all textures to their default values, set the text to an empty string, set the selected state to false
|
||||
|
||||
detailsFramework.TabButtonMixin = {
|
||||
---set the text of the tab button
|
||||
@@ -1214,6 +1240,13 @@ detailsFramework.TabButtonMixin = {
|
||||
self.bIsSelected = selected
|
||||
end,
|
||||
|
||||
---set if the close button can be shown or not
|
||||
---@param self df_tabbutton
|
||||
---@param show boolean
|
||||
SetShowCloseButton = function(self, show)
|
||||
self.CloseButton:SetShown(show)
|
||||
end,
|
||||
|
||||
---get a boolean representing if the tab is selected
|
||||
---@param self df_tabbutton
|
||||
---@return boolean
|
||||
@@ -1232,6 +1265,12 @@ detailsFramework.TabButtonMixin = {
|
||||
self.SelectedTexture:Hide()
|
||||
end,
|
||||
|
||||
---get the fontstring used to display the tab text
|
||||
---@param self df_tabbutton
|
||||
---@return fontstring
|
||||
GetFontString = function(self)
|
||||
return self.Text
|
||||
end,
|
||||
}
|
||||
|
||||
---create a button which can be used as a tab button, has textures for left, right, middle and a text
|
||||
@@ -1255,6 +1294,9 @@ function detailsFramework:CreateTabButton(parent, frameName)
|
||||
tabButton.SelectedTexture:Hide()
|
||||
tabButton.Text = tabButton:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
tabButton.CloseButton = detailsFramework:CreateCloseButton(tabButton, "$parentCloseButton")
|
||||
tabButton.CloseButton:SetSize(10, 10)
|
||||
tabButton.CloseButton:SetAlpha(0.6)
|
||||
tabButton.CloseButton:Hide()
|
||||
|
||||
tabButton.Text:SetPoint("center", tabButton, "center", 0, 0)
|
||||
tabButton.CloseButton:SetPoint("topright", tabButton, "topright", 0, 0)
|
||||
@@ -1294,6 +1336,38 @@ function detailsFramework:CreateTabButton(parent, frameName)
|
||||
return tabButton
|
||||
end
|
||||
|
||||
--[=[
|
||||
--example:
|
||||
local frame = CreateFrame("frame", "MyTestFrameForTabutton", UIParent)
|
||||
frame:SetSize(650, 100)
|
||||
frame:SetPoint("center", UIParent, "center", 0, 0)
|
||||
DetailsFramework:ApplyStandardBackdrop(frame)
|
||||
frame.TabButtons = {}
|
||||
|
||||
local tabOnClickCallback = function(self)
|
||||
for _, tab in ipairs(frame.TabButtons) do
|
||||
tab:SetSelected(false)
|
||||
end
|
||||
self:SetSelected(true)
|
||||
end
|
||||
|
||||
for i = 1, 5 do
|
||||
local tabButton = DetailsFramework:CreateTabButton(frame, "$parentTabButton" .. i)
|
||||
tabButton:SetPoint("bottomleft", frame, "topleft", (i-1) * 130, 0)
|
||||
tabButton:SetText("Tab " .. i)
|
||||
tabButton:SetWidth(128)
|
||||
|
||||
table.insert(frame.TabButtons, tabButton)
|
||||
tabButton:SetScript("OnClick", tabOnClickCallback)
|
||||
end
|
||||
|
||||
--select a tab to be the default selected (if wanted)
|
||||
frame.TabButtons[1]:SetSelected(true)
|
||||
|
||||
--set shown state of the close button (if wanted)
|
||||
frame.TabButtons[2]:SetShowCloseButton(true)
|
||||
--]=]
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--close button
|
||||
|
||||
@@ -1301,9 +1375,11 @@ detailsFramework.CloseButtonMixin = {
|
||||
OnClick = function(self)
|
||||
self:GetParent():Hide()
|
||||
end,
|
||||
|
||||
OnEnter = function(self)
|
||||
self:GetNormalTexture():SetVertexColor(1, 0, 0)
|
||||
end,
|
||||
|
||||
OnLeave = function(self)
|
||||
self:GetNormalTexture():SetVertexColor(1, 1, 1)
|
||||
end,
|
||||
@@ -1318,7 +1394,7 @@ detailsFramework.CloseButtonMixin = {
|
||||
---@param parent frame
|
||||
---@param frameName string|nil
|
||||
---@return df_closebutton
|
||||
function detailsFramework:CreateCloseButton(parent, frameName) --make documentation
|
||||
function detailsFramework:CreateCloseButton(parent, frameName)
|
||||
---@type df_closebutton
|
||||
local closeButton = CreateFrame("button", frameName, parent, "UIPanelCloseButton")
|
||||
closeButton:SetFrameLevel(parent:GetFrameLevel() + 1)
|
||||
|
||||
@@ -392,7 +392,7 @@
|
||||
---@field RegisterForClicks fun(self: button, button1: nil|buttontype, button2: nil|buttontype, button3: nil|buttontype, button4: nil|buttontype)
|
||||
---@field GetNormalTexture fun(self: button) : texture
|
||||
---@field GetPushedTexture fun(self: button) : texture
|
||||
---@field GetHighlightTexture fun(self: button) : texture
|
||||
---@field GetHightlightTexture fun(self: button) : texture
|
||||
---@field GetDisabledTexture fun(self: button) : texture
|
||||
|
||||
---@class statusbar : frame
|
||||
@@ -471,7 +471,7 @@
|
||||
|
||||
---@class texture : region
|
||||
---@field SetDrawLayer fun(self: texture, layer: drawlayer, subLayer: number|nil)
|
||||
---@field SetTexture fun(self: texture, path: string, horizontalWrap: texturewrap|nil, verticalWrap: texturewrap|nil, filter: texturefilter|nil)
|
||||
---@field SetTexture fun(self: texture, path: textureid|texturepath, horizontalWrap: texturewrap|nil, verticalWrap: texturewrap|nil, filter: texturefilter|nil)
|
||||
---@field SetAtlas fun(self: texture, atlas: string)
|
||||
---@field SetColorTexture fun(self: texture, r: red|number, g: green|number, b: blue|number, a: alpha|number|nil)
|
||||
---@field SetDesaturated fun(self: texture, desaturate: boolean)
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
breath_targets = {},
|
||||
flyaway = {},
|
||||
flyaway_timer = {},
|
||||
shield = {},
|
||||
}
|
||||
|
||||
local empower_cache = {}
|
||||
@@ -1257,6 +1258,31 @@
|
||||
end
|
||||
end
|
||||
|
||||
if (spellId == 360828 and augmentation_cache.shield[sourceSerial]) then --shield
|
||||
---actor buffed with the shield -> list of evokers whose buffed
|
||||
---@type table<serial, evokerinfo[]>
|
||||
local currentlyBuffedWithShield = augmentation_cache.shield[sourceSerial]
|
||||
|
||||
for i, evokerInfo in ipairs(currentlyBuffedWithShield) do
|
||||
---@cast evokerInfo evokerinfo
|
||||
|
||||
---@type serial, actorname, controlflags
|
||||
local evokerSourceSerial, evokerSourceName, evokerSourceFlags = unpack(evokerInfo)
|
||||
|
||||
---@type actor
|
||||
local evokerActor = damage_cache[evokerSourceSerial]
|
||||
|
||||
if (not evokerActor) then
|
||||
evokerActor = _current_damage_container:PegarCombatente(evokerSourceSerial, evokerSourceName, evokerSourceFlags, true)
|
||||
end
|
||||
|
||||
if (evokerActor) then
|
||||
local damageSplitted = amount / #currentlyBuffedWithShield
|
||||
evokerActor.total_extra = evokerActor.total_extra + damageSplitted
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (spellId == 404908 and augmentation_cache.prescience[sourceSerial]) then --fate mirror
|
||||
---actor buffed with prescience -> list of evokers whose buffed
|
||||
---@type table<serial, evokerinfo[]>
|
||||
@@ -2610,6 +2636,12 @@
|
||||
table.insert(breathTargets, eonsBreathInfo)
|
||||
end
|
||||
end
|
||||
|
||||
elseif (spellId == 360827) then
|
||||
augmentation_cache.shield[targetSerial] = augmentation_cache.shield[targetSerial] or {}
|
||||
---@type evokerinfo
|
||||
local evokerInfo = {sourceSerial, sourceName, sourceFlags, amount}
|
||||
table.insert(augmentation_cache.shield[targetSerial], evokerInfo)
|
||||
end
|
||||
|
||||
if (buffs_makeyourown[spellId]) then
|
||||
@@ -3025,6 +3057,16 @@
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif (spellid == 360827) then
|
||||
if (augmentation_cache.shield[targetSerial]) then
|
||||
for index, evokerInfo in ipairs(augmentation_cache.shield[targetSerial]) do
|
||||
if (evokerInfo[1] == sourceSerial) then
|
||||
table.remove(augmentation_cache.shield[targetSerial], index)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (buffs_makeyourown[spellid]) then
|
||||
@@ -6425,6 +6467,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
Details:Destroy(augmentation_cache.ebon_might) --~roskash
|
||||
Details:Destroy(augmentation_cache.prescience)
|
||||
Details:Destroy(augmentation_cache.breath_targets)
|
||||
Details:Destroy(augmentation_cache.shield)
|
||||
|
||||
cacheAnything.track_hunter_frenzy = Details.combat_log.track_hunter_frenzy
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
background.blp
|
||||
border_1.blp
|
||||
border_2.blp
|
||||
border_3.blp
|
||||
cooltip_background.blp
|
||||
feedback_sites.blp
|
||||
icons.blp
|
||||
mail.blp
|
||||
*.json
|
||||
CHANGES.txt
|
||||
@@ -1,66 +0,0 @@
|
||||
DFPixelUtil = {};
|
||||
|
||||
function DFPixelUtil.GetPixelToUIUnitFactor()
|
||||
local physicalWidth, physicalHeight = GetPhysicalScreenSize();
|
||||
return 768.0 / physicalHeight;
|
||||
end
|
||||
|
||||
function DFPixelUtil.GetNearestPixelSize(uiUnitSize, layoutScale, minPixels)
|
||||
if uiUnitSize == 0 and (not minPixels or minPixels == 0) then
|
||||
return 0;
|
||||
end
|
||||
|
||||
local uiUnitFactor = DFPixelUtil.GetPixelToUIUnitFactor();
|
||||
local numPixels = Round((uiUnitSize * layoutScale) / uiUnitFactor);
|
||||
local rawNumPixels = numPixels;
|
||||
if minPixels then
|
||||
if uiUnitSize < 0.0 then
|
||||
if numPixels > -minPixels then
|
||||
numPixels = -minPixels;
|
||||
end
|
||||
else
|
||||
if numPixels < minPixels then
|
||||
numPixels = minPixels;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return numPixels * uiUnitFactor / layoutScale;
|
||||
end
|
||||
|
||||
function DFPixelUtil.SetWidth(region, width, minPixels)
|
||||
region:SetWidth(DFPixelUtil.GetNearestPixelSize(width, region:GetEffectiveScale(), minPixels));
|
||||
end
|
||||
|
||||
function DFPixelUtil.SetHeight(region, height, minPixels)
|
||||
region:SetHeight(DFPixelUtil.GetNearestPixelSize(height, region:GetEffectiveScale(), minPixels));
|
||||
end
|
||||
|
||||
function DFPixelUtil.SetSize(region, width, height, minWidthPixels, minHeightPixels)
|
||||
DFPixelUtil.SetWidth(region, width, minWidthPixels);
|
||||
DFPixelUtil.SetHeight(region, height, minHeightPixels);
|
||||
end
|
||||
|
||||
function DFPixelUtil.SetPoint(region, point, relativeTo, relativePoint, offsetX, offsetY, minOffsetXPixels, minOffsetYPixels)
|
||||
region:SetPoint(point, relativeTo, relativePoint,
|
||||
DFPixelUtil.GetNearestPixelSize(offsetX, region:GetEffectiveScale(), minOffsetXPixels),
|
||||
DFPixelUtil.GetNearestPixelSize(offsetY, region:GetEffectiveScale(), minOffsetYPixels)
|
||||
);
|
||||
end
|
||||
|
||||
function DFPixelUtil.SetStatusBarValue(statusBar, value)
|
||||
local width = statusBar:GetWidth();
|
||||
if width and width > 0.0 then
|
||||
local min, max = statusBar:GetMinMaxValues();
|
||||
local percent = ClampedPercentageBetween(value, min, max);
|
||||
if percent == 0.0 or percent == 1.0 then
|
||||
statusBar:SetValue(value);
|
||||
else
|
||||
local numPixels = DFPixelUtil.GetNearestPixelSize(statusBar:GetWidth() * percent, statusBar:GetEffectiveScale());
|
||||
local roundedValue = Lerp(min, max, numPixels / width);
|
||||
statusBar:SetValue(roundedValue);
|
||||
end
|
||||
else
|
||||
statusBar:SetValue(value);
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
## Interface: 100100
|
||||
## Title: Lib: LibDFramework-1.0
|
||||
## Notes: Base Framework for many Addons
|
||||
|
||||
load.xml
|
||||
@@ -1,132 +0,0 @@
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
local _
|
||||
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
--runs when the addon received addon_loaded
|
||||
local addonPreLoad = function(addonFrame, event, ...)
|
||||
--check if the saved variables table is created, if not create one
|
||||
_G[addonFrame.__savedVarsName] = _G[addonFrame.__savedVarsName] or {}
|
||||
|
||||
if (addonFrame.__savedVarsDefaultTemplate) then
|
||||
--load saved vars for this character
|
||||
DF.SavedVars.LoadSavedVarsForPlayer(addonFrame)
|
||||
end
|
||||
|
||||
if (addonFrame.OnLoad) then
|
||||
DF:Dispatch(addonFrame.OnLoad, addonFrame, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--runs when the addon received player_login
|
||||
local addonInit = function(addonFrame, event, ...)
|
||||
if (addonFrame.OnInit) then
|
||||
DF:Dispatch(addonFrame.OnInit, addonFrame, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--when the player logout or reloadUI
|
||||
local addonUnload = function(addonFrame, event, ...)
|
||||
--close saved tables
|
||||
DF.SavedVars.CloseSavedTable(addonFrame.db)
|
||||
end
|
||||
|
||||
local addonEvents = {
|
||||
["ADDON_LOADED"] = addonPreLoad,
|
||||
["PLAYER_LOGIN"] = addonInit,
|
||||
["PLAYER_LOGOUT"] = addonUnload,
|
||||
}
|
||||
|
||||
local addonOnEvent = function(addonFrame, event, ...)
|
||||
local func = addonEvents[event]
|
||||
if (func) then
|
||||
func(addonFrame, event, ...)
|
||||
else
|
||||
--might be a registered event from the user
|
||||
if (addonFrame[event]) then
|
||||
DF:CoreDispatch(addonFrame.__name, addonFrame[event], addonFrame, event, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local getAddonName = function(addonFrame)
|
||||
return addonFrame:GetName()
|
||||
end
|
||||
|
||||
function DF:CreateNewAddOn(addonName, globalSavedVariablesName, savedVarsTemplate)
|
||||
local newAddon = CreateFrame("frame", addonName, UIParent)
|
||||
newAddon.__name = addonName
|
||||
newAddon.__savedVarsName = globalSavedVariablesName
|
||||
newAddon.__savedVarsDefaultTemplate = savedVarsTemplate
|
||||
|
||||
newAddon.GetAddonName = getAddonName
|
||||
|
||||
newAddon:RegisterEvent("ADDON_LOADED")
|
||||
newAddon:RegisterEvent("PLAYER_LOGIN")
|
||||
newAddon:RegisterEvent("PLAYER_LOGOUT")
|
||||
newAddon:SetScript("OnEvent", addonOnEvent)
|
||||
|
||||
return newAddon
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--old create addon
|
||||
function DF:CreateAddOn (name, global_saved, global_table, options_table, broker)
|
||||
|
||||
local addon = LibStub("AceAddon-3.0"):NewAddon (name, "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "DetailsFramework-1.0", "AceComm-3.0")
|
||||
_G [name] = addon
|
||||
addon.__name = name
|
||||
|
||||
function addon:OnInitialize()
|
||||
|
||||
if (global_saved) then
|
||||
if (broker and broker.Minimap and not global_table.Minimap) then
|
||||
DF:Msg(name, "broker.Minimap is true but no global.Minimap declared.")
|
||||
end
|
||||
self.db = LibStub("AceDB-3.0"):New (global_saved, global_table or {}, true)
|
||||
end
|
||||
|
||||
if (options_table) then
|
||||
LibStub("AceConfig-3.0"):RegisterOptionsTable (name, options_table)
|
||||
addon.OptionsFrame1 = LibStub("AceConfigDialog-3.0"):AddToBlizOptions (name, name)
|
||||
|
||||
LibStub("AceConfig-3.0"):RegisterOptionsTable (name .. "-Profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable (self.db))
|
||||
addon.OptionsFrame2 = LibStub("AceConfigDialog-3.0"):AddToBlizOptions (name .. "-Profiles", "Profiles", name)
|
||||
end
|
||||
|
||||
if (broker) then
|
||||
local broker_click_function = broker.OnClick
|
||||
if (not broker_click_function and options_table) then
|
||||
broker_click_function = function()
|
||||
InterfaceOptionsFrame_OpenToCategory (name)
|
||||
InterfaceOptionsFrame_OpenToCategory (name)
|
||||
end
|
||||
end
|
||||
|
||||
local databroker = LibStub("LibDataBroker-1.1"):NewDataObject (name, {
|
||||
type = broker.type or "launcher",
|
||||
icon = broker.icon or [[Interface\PvPRankBadges\PvPRank15]],
|
||||
text = broker.text or "",
|
||||
OnTooltipShow = broker.OnTooltipShow,
|
||||
OnClick = broker_click_function
|
||||
})
|
||||
|
||||
if (databroker and broker.Minimap and global_table.Minimap) then
|
||||
LibStub("LibDBIcon-1.0"):Register (name, databroker, addon.db.profile.Minimap)
|
||||
end
|
||||
end
|
||||
|
||||
if (addon.OnInit) then
|
||||
xpcall(addon.OnInit, geterrorhandler(), addon)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return addon
|
||||
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
<Script file="button.lua"/>
|
||||
</Ui>
|
||||
@@ -1,109 +0,0 @@
|
||||
|
||||
--documentation: see the header of the file charts.lua
|
||||
|
||||
|
||||
--1º example: making a simple chart, just copy and paste this code into a lua file and run it
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample1 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample1")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||
|
||||
--set the data (required)
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24, 18, 17, 14, 15, 8, 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4, 8, 7, 4, 12, 12, 4}
|
||||
local smoothnessLevel = 1 --(optional, default: 1)
|
||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
||||
--draw the chart
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
|
||||
--2º example: setting the color, thickness and scale of the line:
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample2 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample2")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||
|
||||
--set the line thickness (optional, default: 2)
|
||||
local lineThickness = 3
|
||||
ChartFrameTest:SetLineThickness(lineThickness)
|
||||
|
||||
--set the chart color (optional, default: "white")
|
||||
local lineColor = {r = 1, g = 1, b = 0} --set it to "yellow"
|
||||
ChartFrameTest:SetColor(lineColor) --using {r = 1, g = 1, b = 0}
|
||||
ChartFrameTest:SetColor("yellow") --using the color name
|
||||
ChartFrameTest:SetColor(1, 1, 0) --passing the rgb directly
|
||||
ChartFrameTest:SetColor({1, 1, 0}) --using an index table
|
||||
|
||||
--set the data (required)
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||
local smoothnessLevel = 1 --(optional, default: 1)
|
||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
||||
|
||||
--height modifier, if for some reason need to scale the chart height
|
||||
local heightScale = 1 --(optional, default: 1)
|
||||
--draw the chart
|
||||
ChartFrameTest:Plot(heightScale)
|
||||
end
|
||||
|
||||
--3º example: setting the axes lines and labels
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample3 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample3")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
||||
ChartFrameTest:SetSize(800, 600)
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
||||
|
||||
--create guide lines in the left and bottom of the chart
|
||||
local xOffset = 48 --pixels from the left border of the chart
|
||||
local yOffset = 28 --pixels from the bottom border of the chart
|
||||
local whichSide = "left" --which side of vertical line should be placed
|
||||
local thickness = 1
|
||||
local amountYLabels = 10 --amounf of texts indicating the scale of the chart
|
||||
local amountXLabels = 10
|
||||
local r, g, b, a = 1, 1, 1, 1
|
||||
ChartFrameTest:CreateAxesLines(xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, r, g, b, a)
|
||||
|
||||
--the labels in the bottom line can be 'time', 'number' or 'value'
|
||||
ChartFrameTest:SetXAxisDataType("time")
|
||||
--set the data to be used in the bottom line labels, how the data is formatted depends on the type set above
|
||||
ChartFrameTest:SetXAxisData(10) --with type 'time' the chart interprets this as seconds and shows 1:00 to 10:00
|
||||
|
||||
ChartFrameTest:SetXAxisDataType("number")
|
||||
ChartFrameTest:SetXAxisData(600) --the chart interprets this as a 'number' type and displays it as 60, 120, 180.
|
||||
|
||||
ChartFrameTest:SetXAxisDataType("value")
|
||||
ChartFrameTest:SetXAxisData("hello", "world", 1, 2, 3, 4, "chart", 0, 1, 0) --and 'value' show the values passed
|
||||
|
||||
--setting the data, doesn't matter if it is set at the top or right before Plot()
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||
ChartFrameTest:SetData(data) --smoothnessLevel is absent here, it'll use 1 as default
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
|
||||
--4º example: a multi line chart is a chart which supports multiple lines, each line can have a different color, name, smoothnessLevel and thickness
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample4 or DetailsFramework:CreateGraphicMultiLineFrame(UIParent, "ChartFrameExample4")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
||||
ChartFrameTest:SetSize(800, 600)
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
||||
|
||||
--when using multi-line, the Reset() function instructs the chart to discard the previous data as new data is about to be added
|
||||
ChartFrameTest:Reset()
|
||||
|
||||
--smoothnessLevel, name, red, green, blue, alpha
|
||||
local smoothnessLevel = 2 --(optional, default: 0)
|
||||
local line1Name, line2Name, line3Name = "Line 1", "Line 2", "Line 3" --show the line name at the top right corner (optional, default none)
|
||||
local line1Color, line2Color, line3Color = "lime", "purple", "orange" --(optional, default "white")
|
||||
|
||||
--add data into the chart (it plots a line for each data added when :Plot() is called)
|
||||
local data1 = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4}
|
||||
ChartFrameTest:AddData(data1, smoothnessLevel, line1Name, line1Color)
|
||||
|
||||
local data2 = {3, 5, 20, 25, 6, 5, 15, 18, 12, 14, 11, 8, 7, 8 ,7, 4 ,1, 25, 26 , 30, 28, 20, 22, 25, 20, 15, 10, 8, 7, 4, 1, 2, 5, 4}
|
||||
ChartFrameTest:AddData(data2, smoothnessLevel, line2Name, line2Color)
|
||||
|
||||
local data3 = {5, 7, 15, 30, 6, 2, 10, 13, 10, 5, 11, 8, 7, 5, 3, 1, 1, 8, 10 , 12, 15, 20, 25, 25, 20, 17, 12, 7, 7, 6, 4, 5, 6, 5}
|
||||
ChartFrameTest:AddData(data3, smoothnessLevel, line3Name, line3Color)
|
||||
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,184 +0,0 @@
|
||||
do
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
DF.alias_text_colors = DF.alias_text_colors or {}
|
||||
|
||||
local defaultColors = {
|
||||
["HUNTER"] = {0.67, 0.83, 0.45},
|
||||
["WARLOCK"] = {0.58, 0.51, 0.79},
|
||||
["PRIEST"] = {1.0, 1.0, 1.0},
|
||||
["PALADIN"] = {0.96, 0.55, 0.73},
|
||||
["MAGE"] = {0.41, 0.8, 0.94},
|
||||
["ROGUE"] = {1.0, 0.96, 0.41},
|
||||
["DRUID"] = {1.0, 0.49, 0.04},
|
||||
["SHAMAN"] = {0.0, 0.44, 0.87},
|
||||
["WARRIOR"] = {0.78, 0.61, 0.43},
|
||||
["DEATHKNIGHT"] = {0.77, 0.12, 0.23},
|
||||
["MONK"] = {0.0, 1.00, 0.59},
|
||||
["DEMONHUNTER"] = {0.64, 0.19, 0.79},
|
||||
["EVOKER"] = {0.20, 0.58, 0.50},
|
||||
|
||||
["dark1"] = {0.1215, 0.1176, 0.1294},
|
||||
["dark2"] = {0.2215, 0.2176, 0.2294},
|
||||
["dark3"] = {0.3215, 0.3176, 0.3294},
|
||||
|
||||
["aliceblue"] = {0.941176, 0.972549, 1, 1},
|
||||
["antiquewhite"] = {0.980392, 0.921569, 0.843137, 1},
|
||||
["aqua"] = {0, 1, 1, 1},
|
||||
["aquamarine"] = {0.498039, 1, 0.831373, 1},
|
||||
["azure"] = {0.941176, 1, 1, 1},
|
||||
["beige"] = {0.960784, 0.960784, 0.862745, 1},
|
||||
["bisque"] = {1, 0.894118, 0.768627, 1},
|
||||
["black"] = {0, 0, 0, 1},
|
||||
["blanchedalmond"] = {1, 0.921569, 0.803922, 1},
|
||||
["blue"] = {0, 0, 1, 1},
|
||||
["blueviolet"] = {0.541176, 0.168627, 0.886275, 1},
|
||||
["brown"] = {0.647059, 0.164706, 0.164706, 1},
|
||||
["burlywood"] = {0.870588, 0.721569, 0.529412, 1},
|
||||
["cadetblue"] = {0.372549, 0.619608, 0.627451, 1},
|
||||
["chartreuse"] = {0.498039, 1, 0, 1},
|
||||
["chocolate"] = {0.823529, 0.411765, 0.117647, 1},
|
||||
["coral"] = {1, 0.498039, 0.313725, 1},
|
||||
["cornflowerblue"] = {0.392157, 0.584314, 0.929412, 1},
|
||||
["cornsilk"] = {1, 0.972549, 0.862745, 1},
|
||||
["crimson"] = {0.862745, 0.0784314, 0.235294, 1},
|
||||
["cyan"] = {0, 1, 1, 1},
|
||||
["darkblue"] = {0, 0, 0.545098, 1},
|
||||
["darkcyan"] = {0, 0.545098, 0.545098, 1},
|
||||
["darkgoldenrod"] = {0.721569, 0.52549, 0.0431373, 1},
|
||||
["darkgray"] = {0.662745, 0.662745, 0.662745, 1},
|
||||
["darkgreen"] = {0, 0.392157, 0, 1},
|
||||
["darkkhaki"] = {0.741176, 0.717647, 0.419608, 1},
|
||||
["darkmagenta"] = {0.545098, 0, 0.545098, 1},
|
||||
["darkolivegreen"] = {0.333333, 0.419608, 0.184314, 1},
|
||||
["darkorange"] = {1, 0.54902, 0, 1},
|
||||
["darkorchid"] = {0.6, 0.196078, 0.8, 1},
|
||||
["darkred"] = {0.545098, 0, 0, 1},
|
||||
["darksalmon"] = {0.913725, 0.588235, 0.478431, 1},
|
||||
["darkseagreen"] = {0.560784, 0.737255, 0.560784, 1},
|
||||
["darkslateblue"] = {0.282353, 0.239216, 0.545098, 1},
|
||||
["darkslategray"] = {0.184314, 0.309804, 0.309804, 1},
|
||||
["darkturquoise"] = {0, 0.807843, 0.819608, 1},
|
||||
["darkviolet"] = {0.580392, 0, 0.827451, 1},
|
||||
["deeppink"] = {1, 0.0784314, 0.576471, 1},
|
||||
["deepskyblue"] = {0, 0.74902, 1, 1},
|
||||
["dimgray"] = {0.411765, 0.411765, 0.411765, 1},
|
||||
["dimgrey"] = {0.411765, 0.411765, 0.411765, 1},
|
||||
["dodgerblue"] = {0.117647, 0.564706, 1, 1},
|
||||
["firebrick"] = {0.698039, 0.133333, 0.133333, 1},
|
||||
["firebrickdark"] = {0.258039, 0.033333, 0.033333, 1},
|
||||
["floralwhite"] = {1, 0.980392, 0.941176, 1},
|
||||
["forestgreen"] = {0.133333, 0.545098, 0.133333, 1},
|
||||
["fuchsia"] = {1, 0, 1, 1},
|
||||
["gainsboro"] = {0.862745, 0.862745, 0.862745, 1},
|
||||
["ghostwhite"] = {0.972549, 0.972549, 1, 1},
|
||||
["gold"] = {1, 0.843137, 0, 1},
|
||||
["goldenrod"] = {0.854902, 0.647059, 0.12549, 1},
|
||||
["gray"] = {0.501961, 0.501961, 0.501961, 1},
|
||||
["green"] = {0, 0.501961, 0, 1},
|
||||
["greenyellow"] = {0.678431, 1, 0.184314, 1},
|
||||
["honeydew"] = {0.941176, 1, 0.941176, 1},
|
||||
["hotpink"] = {1, 0.411765, 0.705882, 1},
|
||||
["indianred"] = {0.803922, 0.360784, 0.360784, 1},
|
||||
["indigo"] = {0.294118, 0, 0.509804, 1},
|
||||
["ivory"] = {1, 1, 0.941176, 1},
|
||||
["khaki"] = {0.941176, 0.901961, 0.54902, 1},
|
||||
["lavender"] = {0.901961, 0.901961, 0.980392, 1},
|
||||
["lavenderblush"] = {1, 0.941176, 0.960784, 1},
|
||||
["lawngreen"] = {0.486275, 0.988235, 0, 1},
|
||||
["lemonchiffon"] = {1, 0.980392, 0.803922, 1},
|
||||
["lightblue"] = {0.678431, 0.847059, 0.901961, 1},
|
||||
["lightcoral"] = {0.941176, 0.501961, 0.501961, 1},
|
||||
["lightcyan"] = {0.878431, 1, 1, 1},
|
||||
["lightgoldenrodyellow"] = {0.980392, 0.980392, 0.823529, 1},
|
||||
["lightgray"] = {0.827451, 0.827451, 0.827451, 1},
|
||||
["lightgreen"] = {0.564706, 0.933333, 0.564706, 1},
|
||||
["lightpink"] = {1, 0.713725, 0.756863, 1},
|
||||
["lightsalmon"] = {1, 0.627451, 0.478431, 1},
|
||||
["lightseagreen"] = {0.12549, 0.698039, 0.666667, 1},
|
||||
["lightskyblue"] = {0.529412, 0.807843, 0.980392, 1},
|
||||
["lightslategray"] = {0.466667, 0.533333, 0.6, 1},
|
||||
["lightsteelblue"] = {0.690196, 0.768627, 0.870588, 1},
|
||||
["lightyellow"] = {1, 1, 0.878431, 1},
|
||||
["lime"] = {0, 1, 0, 1},
|
||||
["limegreen"] = {0.196078, 0.803922, 0.196078, 1},
|
||||
["linen"] = {0.980392, 0.941176, 0.901961, 1},
|
||||
["magenta"] = {1, 0, 1, 1},
|
||||
["maroon"] = {0.501961, 0, 0, 1},
|
||||
["mediumaquamarine"] = {0.4, 0.803922, 0.666667, 1},
|
||||
["mediumblue"] = {0, 0, 0.803922, 1},
|
||||
["mediumorchid"] = {0.729412, 0.333333, 0.827451, 1},
|
||||
["mediumpurple"] = {0.576471, 0.439216, 0.858824, 1},
|
||||
["mediumseagreen"] = {0.235294, 0.701961, 0.443137, 1},
|
||||
["mediumslateblue"] = {0.482353, 0.407843, 0.933333, 1},
|
||||
["mediumspringgreen"] = {0, 0.980392, 0.603922, 1},
|
||||
["mediumturquoise"] = {0.282353, 0.819608, 0.8, 1},
|
||||
["mediumvioletred"] = {0.780392, 0.0823529, 0.521569, 1},
|
||||
["midnightblue"] = {0.0980392, 0.0980392, 0.439216, 1},
|
||||
["mintcream"] = {0.960784, 1, 0.980392, 1},
|
||||
["mistyrose"] = {1, 0.894118, 0.882353, 1},
|
||||
["moccasin"] = {1, 0.894118, 0.709804, 1},
|
||||
["navajowhite"] = {1, 0.870588, 0.678431, 1},
|
||||
["navy"] = {0, 0, 0.501961, 1},
|
||||
["none"] ={0, 0, 0, 0},
|
||||
["oldlace"] = {0.992157, 0.960784, 0.901961, 1},
|
||||
["olive"] = {0.501961, 0.501961, 0, 1},
|
||||
["olivedrab"] = {0.419608, 0.556863, 0.137255, 1},
|
||||
["orange"] = {1, 0.647059, 0, 1},
|
||||
["orangered"] = {1, 0.270588, 0, 1},
|
||||
["orchid"] = {0.854902, 0.439216, 0.839216, 1},
|
||||
["palegoldenrod"] = {0.933333, 0.909804, 0.666667, 1},
|
||||
["palegreen"] = {0.596078, 0.984314, 0.596078, 1},
|
||||
["paleturquoise"] = {0.686275, 0.933333, 0.933333, 1},
|
||||
["palevioletred"] = {0.858824, 0.439216, 0.576471, 1},
|
||||
["papayawhip"] = {1, 0.937255, 0.835294, 1},
|
||||
["peachpuff"] = {1, 0.854902, 0.72549, 1},
|
||||
["peru"] = {0.803922, 0.521569, 0.247059, 1},
|
||||
["pink"] = {1, 0.752941, 0.796078, 1},
|
||||
["plum"] = {0.866667, 0.627451, 0.866667, 1},
|
||||
["powderblue"] = {0.690196, 0.878431, 0.901961, 1},
|
||||
["purple"] = {0.501961, 0, 0.501961, 1},
|
||||
["red"] = {1, 0, 0, 1},
|
||||
["rosybrown"] = {0.737255, 0.560784, 0.560784, 1},
|
||||
["royalblue"] = {0.254902, 0.411765, 0.882353, 1},
|
||||
["saddlebrown"] = {0.545098, 0.270588, 0.0745098, 1},
|
||||
["salmon"] = {0.980392, 0.501961, 0.447059, 1},
|
||||
["sandybrown"] = {0.956863, 0.643137, 0.376471, 1},
|
||||
["seagreen"] = {0.180392, 0.545098, 0.341176, 1},
|
||||
["seashell"] = {1, 0.960784, 0.933333, 1},
|
||||
["sienna"] = {0.627451, 0.321569, 0.176471, 1},
|
||||
["silver"] = {0.752941, 0.752941, 0.752941, 1},
|
||||
["skyblue"] = {0.529412, 0.807843, 0.921569, 1},
|
||||
["slateblue"] = {0.415686, 0.352941, 0.803922, 1},
|
||||
["slategray"] = {0.439216, 0.501961, 0.564706, 1},
|
||||
["snow"] = {1, 0.980392, 0.980392, 1},
|
||||
["springgreen"] = {0, 1, 0.498039, 1},
|
||||
["steelblue"] = {0.27451, 0.509804, 0.705882, 1},
|
||||
["tan"] = {0.823529, 0.705882, 0.54902, 1},
|
||||
["teal"] = {0, 0.501961, 0.501961, 1},
|
||||
["thistle"] = {0.847059, 0.74902, 0.847059, 1},
|
||||
["tomato"] = {1, 0.388235, 0.278431, 1},
|
||||
["transparent"] ={0, 0, 0, 0},
|
||||
["turquoise"] = {0.25098, 0.878431, 0.815686, 1},
|
||||
["violet"] = {0.933333, 0.509804, 0.933333, 1},
|
||||
["wheat"] = {0.960784, 0.870588, 0.701961, 1},
|
||||
["white"] = {1, 1, 1, 1},
|
||||
["whitesmoke"] = {0.960784, 0.960784, 0.960784, 1},
|
||||
["yellow"] = {1, 1, 0, 1},
|
||||
["yellowgreen"] = {0.603922, 0.803922, 0.196078, 1}
|
||||
}
|
||||
|
||||
function DF:GetDefaultColorList()
|
||||
return defaultColors
|
||||
end
|
||||
|
||||
for colorName, colorTable in pairs(defaultColors) do
|
||||
DF.alias_text_colors [colorName] = colorTable
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,565 +0,0 @@
|
||||
|
||||
local detailsFramework = _G ["DetailsFramework"]
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local DF = detailsFramework
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local wipe = wipe
|
||||
local unpack = unpack
|
||||
|
||||
---@class df_framecontainer : frame, dfframecontainermixin, df_optionsmixin
|
||||
---@field bIsSizing boolean
|
||||
---@field options table
|
||||
---@field currentWidth number
|
||||
---@field currentHeight number
|
||||
---@field bottomLeftResizer framecontainerresizer
|
||||
---@field bottomRightResizer framecontainerresizer
|
||||
---@field topLeftResizer framecontainerresizer
|
||||
---@field topRightResizer framecontainerresizer
|
||||
---@field topResizer framecontainerresizer
|
||||
---@field bottomResizer framecontainerresizer
|
||||
---@field leftResizer framecontainerresizer
|
||||
---@field rightResizer framecontainerresizer
|
||||
---@field cornerResizers framecontainerresizer[]
|
||||
---@field sideResizers framecontainerresizer[]
|
||||
---@field components table<frame, boolean>
|
||||
---@field moverFrame frame
|
||||
---@field movableChildren table<frame, boolean>
|
||||
---@field settingChangedCallback fun(frameContainer: df_framecontainer, settingName: string, settingValue: any)
|
||||
---@field OnSizeChanged fun(frameContainer: df_framecontainer)
|
||||
---@field OnResizerMouseDown fun(resizerButton: button, mouseButton: string)
|
||||
---@field OnResizerMouseUp fun(resizerButton: button, mouseButton: string)
|
||||
---@field HideResizer fun(frameContainer: df_framecontainer)
|
||||
---@field ShowResizer fun(frameContainer: df_framecontainer)
|
||||
---@field OnInitialize fun(frameContainer: df_framecontainer)
|
||||
---@field SetResizeLocked fun(frameContainer: df_framecontainer, isLocked: boolean)
|
||||
---@field SetMovableLocked fun(frameContainer: df_framecontainer, isLocked: boolean)
|
||||
---@field CheckResizeLockedState fun(frameContainer: df_framecontainer)
|
||||
---@field CheckMovableLockedState fun(frameContainer: df_framecontainer)
|
||||
---@field CreateMover fun(frameContainer: df_framecontainer)
|
||||
---@field CreateResizers fun(frameContainer: df_framecontainer)
|
||||
---@field RegisterChildForDrag fun(frameContainer: df_framecontainer, child: frame)
|
||||
---@field UnregisterChildForDrag fun(frameContainer: df_framecontainer, child: frame)
|
||||
---@field RefreshChildrenState fun(frameContainer: df_framecontainer)
|
||||
---@field OnChildDragStart fun(frameContainer: df_framecontainer, child: frame)
|
||||
---@field OnChildDragStop fun(frameContainer: df_framecontainer, child: frame)
|
||||
---@field SetSettingChangedCallback fun(frameContainer: df_framecontainer, callback: fun(frameContainer: df_framecontainer, settingName: string, settingValue: any))
|
||||
---@field SendSettingChangedCallback fun(frameContainer: df_framecontainer, settingName: string, settingValue: any)
|
||||
|
||||
|
||||
|
||||
---@class framecontainerresizer : button
|
||||
---@field sizingFrom string
|
||||
|
||||
---@class dfframecontainermixin
|
||||
detailsFramework.FrameContainerMixin = {
|
||||
--methods
|
||||
|
||||
---run when the user click on the resizer
|
||||
---@param resizerButton framecontainerresizer
|
||||
---@param mouseButton string
|
||||
OnResizerMouseDown = function(resizerButton, mouseButton)
|
||||
if (mouseButton ~= "LeftButton") then
|
||||
return
|
||||
end
|
||||
|
||||
---@type df_framecontainer
|
||||
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `df_framecontainer`. .. but df_framecontainer is inherited from frame
|
||||
|
||||
if (frameContainer.bIsSizing) then
|
||||
return
|
||||
end
|
||||
|
||||
frameContainer.bIsSizing = true
|
||||
frameContainer:StartSizing(resizerButton.sizingFrom)
|
||||
end,
|
||||
|
||||
---run when the user click on the resizer
|
||||
---@param resizerButton framecontainerresizer
|
||||
---@param mouseButton string
|
||||
OnResizerMouseUp = function(resizerButton, mouseButton)
|
||||
---@type df_framecontainer
|
||||
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `df_framecontainer`. .. but df_framecontainer is inherited from frame
|
||||
|
||||
if (not frameContainer.bIsSizing) then
|
||||
return
|
||||
end
|
||||
|
||||
frameContainer:StopMovingOrSizing()
|
||||
frameContainer.bIsSizing = false
|
||||
end,
|
||||
|
||||
---hide resizer
|
||||
---@param frameContainer df_framecontainer
|
||||
HideResizer = function(frameContainer)
|
||||
for i = 1, #frameContainer.cornerResizers do
|
||||
frameContainer.cornerResizers[i]:Hide()
|
||||
end
|
||||
|
||||
for i = 1, #frameContainer.sideResizers do
|
||||
frameContainer.sideResizers[i]:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
---show resizer
|
||||
---@param frameContainer df_framecontainer
|
||||
ShowResizer = function(frameContainer)
|
||||
--corner resizers
|
||||
if (frameContainer.options.use_bottomleft_resizer) then
|
||||
frameContainer.bottomLeftResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_bottomright_resizer) then
|
||||
frameContainer.bottomRightResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_topleft_resizer) then
|
||||
frameContainer.topRightResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_topright_resizer) then
|
||||
frameContainer.topRightResizer:Show()
|
||||
end
|
||||
|
||||
--side resizers
|
||||
if (frameContainer.options.use_top_resizer) then
|
||||
frameContainer.topResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_bottom_resizer) then
|
||||
frameContainer.bottomResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_left_resizer) then
|
||||
frameContainer.leftResizer:Show()
|
||||
end
|
||||
if (frameContainer.options.use_right_resizer) then
|
||||
frameContainer.rightResizer:Show()
|
||||
end
|
||||
end,
|
||||
|
||||
---check the lock state and show or hide the resizer, set the frame as movable or not, resizeable or not
|
||||
---@param frameContainer df_framecontainer
|
||||
CheckResizeLockedState = function(frameContainer)
|
||||
if (frameContainer.options.is_locked) then
|
||||
frameContainer:HideResizer()
|
||||
frameContainer:SetResizable(false)
|
||||
else
|
||||
frameContainer:ShowResizer()
|
||||
frameContainer:SetResizable(true)
|
||||
end
|
||||
end,
|
||||
|
||||
---check if the framecontainer can be moved and show or hide the mover
|
||||
---@param frameContainer df_framecontainer
|
||||
CheckMovableLockedState = function(frameContainer)
|
||||
if (frameContainer.options.is_movement_locked) then
|
||||
frameContainer:SetMovable(false)
|
||||
frameContainer:EnableMouse(false)
|
||||
frameContainer.moverFrame:Hide()
|
||||
else
|
||||
frameContainer:SetMovable(true)
|
||||
frameContainer:EnableMouse(true)
|
||||
frameContainer.moverFrame:Show()
|
||||
end
|
||||
end,
|
||||
|
||||
---set the lock state
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param isLocked boolean
|
||||
SetResizeLocked = function(frameContainer, isLocked)
|
||||
frameContainer.options.is_locked = isLocked
|
||||
frameContainer:SendSettingChangedCallback("is_locked", isLocked)
|
||||
frameContainer:CheckResizeLockedState()
|
||||
end,
|
||||
|
||||
---set the state of the mover frame
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param isLocked boolean
|
||||
SetMovableLocked = function(frameContainer, isLocked)
|
||||
frameContainer.options.is_movement_locked = isLocked
|
||||
frameContainer:SendSettingChangedCallback("is_movement_locked", isLocked)
|
||||
frameContainer:CheckMovableLockedState()
|
||||
end,
|
||||
|
||||
---create a mover to move the frame
|
||||
---@param frameContainer df_framecontainer
|
||||
CreateMover = function(frameContainer)
|
||||
local mover = CreateFrame("button", nil, frameContainer)
|
||||
frameContainer.moverFrame = mover
|
||||
mover:SetAllPoints(frameContainer)
|
||||
mover:EnableMouse(false)
|
||||
mover:SetMovable(true)
|
||||
mover:SetScript("OnMouseDown", function(self, mouseButton)
|
||||
if (mouseButton ~= "LeftButton" or frameContainer.options.is_movement_locked) then
|
||||
return
|
||||
end
|
||||
frameContainer:StartMoving()
|
||||
end)
|
||||
mover:SetScript("OnMouseUp", function(self, mouseButton)
|
||||
if (mouseButton ~= "LeftButton" or frameContainer.options.is_movement_locked) then
|
||||
return
|
||||
end
|
||||
frameContainer:StopMovingOrSizing()
|
||||
end)
|
||||
end,
|
||||
|
||||
---create four corner resizer and four side resizer
|
||||
---@param frameContainer df_framecontainer
|
||||
CreateResizers = function(frameContainer)
|
||||
local parent = frameContainer:GetParent()
|
||||
--create resizers for the container corners
|
||||
local bottomLeftResizer, bottomRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "BottomLeftResizer", parent:GetName() .. "BottomRightResizer")
|
||||
frameContainer.bottomLeftResizer = bottomLeftResizer
|
||||
frameContainer.bottomRightResizer = bottomRightResizer
|
||||
|
||||
local topLeftResizer, topRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopLeftResizer", parent:GetName() .. "TopRightResizer")
|
||||
frameContainer.topLeftResizer = topLeftResizer
|
||||
frameContainer.topRightResizer = topRightResizer
|
||||
|
||||
local topResizer, bottomResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopResizer", parent:GetName() .. "BottomResizer")
|
||||
frameContainer.topResizer = topResizer
|
||||
frameContainer.bottomResizer = bottomResizer
|
||||
|
||||
local leftResizer, rightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "LeftResizer", parent:GetName() .. "RightResizer")
|
||||
frameContainer.leftResizer = leftResizer
|
||||
frameContainer.rightResizer = rightResizer
|
||||
|
||||
frameContainer.cornerResizers = {
|
||||
bottomLeftResizer,
|
||||
bottomRightResizer,
|
||||
topLeftResizer,
|
||||
topRightResizer,
|
||||
}
|
||||
|
||||
frameContainer.sideResizers = {
|
||||
topResizer,
|
||||
bottomResizer,
|
||||
leftResizer,
|
||||
rightResizer,
|
||||
}
|
||||
|
||||
--add all resizers to the frameContainer.components table
|
||||
for i = 1, #frameContainer.cornerResizers do
|
||||
frameContainer.components[frameContainer.cornerResizers[i]] = true
|
||||
end
|
||||
for i = 1, #frameContainer.sideResizers do
|
||||
frameContainer.components[frameContainer.sideResizers[i]] = true
|
||||
end
|
||||
|
||||
--hide all resizers
|
||||
frameContainer:HideResizer()
|
||||
end,
|
||||
|
||||
---run when the container is created
|
||||
---@param frameContainer df_framecontainer
|
||||
OnInitialize = function(frameContainer) --õninit ~init ~oninit
|
||||
--set the default members
|
||||
frameContainer.bIsSizing = false
|
||||
frameContainer:SetSize(frameContainer.options.width, frameContainer.options.height)
|
||||
|
||||
--iterate among the corner resizers and set the mouse down and up scripts
|
||||
for i = 1, #frameContainer.cornerResizers do
|
||||
frameContainer.cornerResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
|
||||
frameContainer.cornerResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
|
||||
end
|
||||
|
||||
local sideResizeThickness = 2
|
||||
|
||||
--iterate among the side resizers and set the mouse down and up scripts; set the texture color; clear all points; set the thickness
|
||||
for i = 1, #frameContainer.sideResizers do
|
||||
frameContainer.sideResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
|
||||
frameContainer.sideResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
|
||||
|
||||
frameContainer.sideResizers[i]:GetNormalTexture():SetColorTexture(1, 1, 1, 0.6)
|
||||
frameContainer.sideResizers[i]:GetHighlightTexture():SetColorTexture(detailsFramework:ParseColors("aqua"))
|
||||
frameContainer.sideResizers[i]:GetPushedTexture():SetColorTexture(1, 1, 1, 1)
|
||||
|
||||
frameContainer.sideResizers[i]:ClearAllPoints()
|
||||
|
||||
--can use SetSize here because the width or height are set by the point, e.g. 'topleft' to 'topright' overwrite the width set here
|
||||
frameContainer.sideResizers[i]:SetSize(sideResizeThickness, sideResizeThickness)
|
||||
end
|
||||
|
||||
--flip the corner resizers texturess
|
||||
frameContainer.topLeftResizer:GetNormalTexture():SetTexCoord(1, 0, 1, 0)
|
||||
frameContainer.topLeftResizer:GetHighlightTexture():SetTexCoord(1, 0, 1, 0)
|
||||
frameContainer.topLeftResizer:GetPushedTexture():SetTexCoord(1, 0, 1, 0)
|
||||
frameContainer.topRightResizer:GetNormalTexture():SetTexCoord(0, 1, 1, 0)
|
||||
frameContainer.topRightResizer:GetHighlightTexture():SetTexCoord(0, 1, 1, 0)
|
||||
frameContainer.topRightResizer:GetPushedTexture():SetTexCoord(0, 1, 1, 0)
|
||||
frameContainer.topLeftResizer:ClearAllPoints()
|
||||
frameContainer.topLeftResizer:SetPoint("topleft", frameContainer, "topleft", 0, 0)
|
||||
frameContainer.topRightResizer:ClearAllPoints()
|
||||
frameContainer.topRightResizer:SetPoint("topright", frameContainer, "topright", 0, 0)
|
||||
|
||||
--resize from for the corner resizers
|
||||
frameContainer.bottomLeftResizer.sizingFrom = "bottomleft"
|
||||
frameContainer.bottomRightResizer.sizingFrom = "bottomright"
|
||||
frameContainer.topLeftResizer.sizingFrom = "topleft"
|
||||
frameContainer.topRightResizer.sizingFrom = "topright"
|
||||
|
||||
--resize from for the side resizers
|
||||
frameContainer.topResizer.sizingFrom = "top"
|
||||
frameContainer.bottomResizer.sizingFrom = "bottom"
|
||||
frameContainer.leftResizer.sizingFrom = "left"
|
||||
frameContainer.rightResizer.sizingFrom = "right"
|
||||
|
||||
--set the side resizer points
|
||||
frameContainer.topResizer:SetPoint("topleft", frameContainer, "topleft", 0, 2)
|
||||
frameContainer.topResizer:SetPoint("topright", frameContainer, "topright", 0, 2)
|
||||
frameContainer.bottomResizer:SetPoint("bottomleft", frameContainer, "bottomleft", 0, -2)
|
||||
frameContainer.bottomResizer:SetPoint("bottomright", frameContainer, "bottomright", 0, -2)
|
||||
frameContainer.leftResizer:SetPoint("topleft", frameContainer, "topleft", -2, 0)
|
||||
frameContainer.leftResizer:SetPoint("bottomleft", frameContainer, "bottomleft", -2, 0)
|
||||
frameContainer.rightResizer:SetPoint("topright", frameContainer, "topright", 2, 0)
|
||||
frameContainer.rightResizer:SetPoint("bottomright", frameContainer, "bottomright", 2, 0)
|
||||
|
||||
if (frameContainer.options.is_locked) then
|
||||
frameContainer:HideResizer()
|
||||
else
|
||||
frameContainer:ShowResizer()
|
||||
end
|
||||
|
||||
frameContainer:CheckResizeLockedState()
|
||||
frameContainer:CheckMovableLockedState()
|
||||
|
||||
if (frameContainer.SetMinResize) then --old versions of the game uses this method
|
||||
frameContainer:SetMinResize(50, 50)
|
||||
frameContainer:SetMaxResize(1000,1000)
|
||||
else
|
||||
frameContainer:SetResizeBounds(50, 50, 1000, 1000) --new versions has this method
|
||||
end
|
||||
end,
|
||||
|
||||
---run when the container has its size changed
|
||||
---@param frameContainer df_framecontainer
|
||||
OnSizeChanged = function(frameContainer)
|
||||
---@type frame[]
|
||||
local children = {frameContainer:GetChildren()}
|
||||
---@type number
|
||||
local childrenAmount = #children
|
||||
|
||||
--get the container size before its size was changed and calculate the percent of the difference between the old size and the new size
|
||||
--adding +1 to the width and height difference to prevent the child from shrinking to 0, so it is scaled by 1
|
||||
---@type number
|
||||
local widthDifference = 1 + (frameContainer:GetWidth() - frameContainer.currentWidth) / frameContainer.currentWidth
|
||||
---@type number
|
||||
local heightDifference = 1 + (frameContainer:GetHeight() - frameContainer.currentHeight) / frameContainer.currentHeight
|
||||
|
||||
for i = 1, childrenAmount do
|
||||
---@type frame
|
||||
local child = children[i]
|
||||
--if the child is a component, skip it
|
||||
if (not frameContainer.components[child]) then
|
||||
child:SetWidth(child:GetWidth() * widthDifference)
|
||||
child:SetHeight(child:GetHeight() * heightDifference)
|
||||
end
|
||||
end
|
||||
|
||||
--update the current size of the container
|
||||
frameContainer.currentWidth = frameContainer:GetWidth()
|
||||
frameContainer.currentHeight = frameContainer:GetHeight()
|
||||
|
||||
frameContainer:SendSettingChangedCallback("width", frameContainer.currentWidth)
|
||||
frameContainer:SendSettingChangedCallback("height", frameContainer.currentHeight)
|
||||
end,
|
||||
|
||||
OnChildDragStop = function(child)
|
||||
child:StopMovingOrSizing()
|
||||
child:SetScript("OnUpdate", nil)
|
||||
end,
|
||||
|
||||
---@param child frame
|
||||
OnChildDragStart = function(child)
|
||||
---@type df_framecontainer
|
||||
local frameContainer = child:GetParent()
|
||||
|
||||
---get the coordinates for the frame container, which is called 'boundingBox' for convenience
|
||||
---@type objectcoordinates
|
||||
local boundingBox = detailsFramework:GetObjectCoordinates(frameContainer)
|
||||
|
||||
child:StartMoving()
|
||||
|
||||
--save the current point of the child, so it can be restored if the child is dragged outside the container
|
||||
local childPoints = {}
|
||||
for pointIndex = 1, child:GetNumPoints() do
|
||||
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
|
||||
end
|
||||
|
||||
child:SetScript("OnUpdate", function(self)
|
||||
---@type objectcoordinates
|
||||
local childPos = detailsFramework:GetObjectCoordinates(self)
|
||||
--check if the borders of the rectangle 'rec' collided with the borders of the rectangle 'bbox'
|
||||
if ((childPos.left < boundingBox.left or childPos.right > boundingBox.right) or (childPos.top > boundingBox.top or childPos.bottom < boundingBox.bottom)) then
|
||||
child:ClearAllPoints()
|
||||
for pointIndex = 1, #childPoints do
|
||||
child:SetPoint(unpack(childPoints[pointIndex]))
|
||||
end
|
||||
else
|
||||
wipe(childPoints)
|
||||
for pointIndex = 1, child:GetNumPoints() do
|
||||
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
---check if the children can be moved and set the properties on thisFrame
|
||||
---@param frameContainer df_framecontainer
|
||||
RefreshChildrenState = function(frameContainer)
|
||||
frameContainer:EnableMouse(true)
|
||||
if (frameContainer.options.can_move_children) then
|
||||
for child, _ in pairs(frameContainer.movableChildren) do
|
||||
child:EnableMouse(true)
|
||||
child:SetMovable(true)
|
||||
child:RegisterForDrag("LeftButton")
|
||||
child:SetScript("OnDragStart", detailsFramework.FrameContainerMixin.OnChildDragStart)
|
||||
child:SetScript("OnDragStop", detailsFramework.FrameContainerMixin.OnChildDragStop)
|
||||
end
|
||||
else
|
||||
for child, _ in pairs(frameContainer.movableChildren) do
|
||||
child:EnableMouse(false)
|
||||
child:SetMovable(false)
|
||||
child:RegisterForDrag("")
|
||||
child:SetScript("OnDragStart", nil)
|
||||
child:SetScript("OnDragStop", nil)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param child frame
|
||||
RegisterChildForDrag = function(frameContainer, child)
|
||||
frameContainer.movableChildren[child] = true
|
||||
frameContainer:RefreshChildrenState()
|
||||
child:SetFrameStrata(frameContainer:GetFrameStrata())
|
||||
child:SetFrameLevel(frameContainer:GetFrameLevel() + 1)
|
||||
end,
|
||||
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param child frame
|
||||
UnregisterChildForDrag = function(frameContainer, child)
|
||||
frameContainer.movableChildren[child] = nil
|
||||
frameContainer:RefreshChildrenState()
|
||||
end,
|
||||
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param callback function
|
||||
SetSettingChangedCallback = function(frameContainer, callback)
|
||||
frameContainer.settingChangedCallback = callback
|
||||
end,
|
||||
|
||||
---send a callback to the setting changed callback
|
||||
---@param frameContainer df_framecontainer
|
||||
---@param key string
|
||||
---@param value any
|
||||
SendSettingChangedCallback = function(frameContainer, key, value)
|
||||
if (type(frameContainer.settingChangedCallback) == "function") then
|
||||
detailsFramework:Dispatch(frameContainer.settingChangedCallback, frameContainer, key, value)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---these are the default settings for the frame container; these keys can be accessed by df_framecontainer.options[key]
|
||||
---@type table<string, any>
|
||||
local frameContainerOptions = {
|
||||
--default settings
|
||||
width = 300,
|
||||
height = 150,
|
||||
is_locked = true, --can or not be resized
|
||||
is_movement_locked = true, --can or not be moved
|
||||
can_move_children = true,
|
||||
use_topleft_resizer = false,
|
||||
use_topright_resizer = false,
|
||||
use_bottomleft_resizer = false,
|
||||
use_bottomright_resizer = false,
|
||||
use_top_resizer = false,
|
||||
use_bottom_resizer = false,
|
||||
use_left_resizer = false,
|
||||
use_right_resizer = false,
|
||||
}
|
||||
|
||||
---create a frame container, which is a frame that envelops another frame, and can be moved, resized, etc.
|
||||
---@param parent frame
|
||||
---@param options table|nil
|
||||
---@param frameName string|nil
|
||||
---@return df_framecontainer
|
||||
function DF:CreateFrameContainer(parent, options, frameName)
|
||||
---@type df_framecontainer
|
||||
local frameContainer = CreateFrame("frame", frameName or ("$parentFrameContainer" .. math.random(10000, 99999)), parent, "BackdropTemplate")
|
||||
frameContainer.components = {}
|
||||
frameContainer.movableChildren = {}
|
||||
frameContainer:EnableMouse(false)
|
||||
|
||||
detailsFramework:Mixin(frameContainer, detailsFramework.FrameContainerMixin)
|
||||
detailsFramework:Mixin(frameContainer, detailsFramework.OptionsFunctions)
|
||||
|
||||
frameContainer:CreateResizers()
|
||||
frameContainer:CreateMover()
|
||||
frameContainer:BuildOptionsTable(frameContainerOptions, options)
|
||||
|
||||
frameContainer:OnInitialize()
|
||||
|
||||
frameContainer.currentWidth = frameContainer:GetWidth()
|
||||
frameContainer.currentHeight = frameContainer:GetHeight()
|
||||
frameContainer:SetScript("OnSizeChanged", frameContainer.OnSizeChanged)
|
||||
|
||||
return frameContainer
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function DF:CreateFrameContainerTest(parent, options, frameName)
|
||||
local container = DF:CreateFrameContainer(parent, options, frameName)
|
||||
container:SetSize(400, 400)
|
||||
container:SetPoint("center", _G.UIParent, "center", 0, 0)
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(container)
|
||||
|
||||
local verticalLastBox = nil
|
||||
for i = 1, 4 do
|
||||
local lastBox = nil
|
||||
for o = 1, 4 do
|
||||
local frame = CreateFrame("frame", "$parentFrame" .. i .. o, container, "BackdropTemplate")
|
||||
container:RegisterChildForDrag(frame)
|
||||
|
||||
frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
frame:SetBackdropColor(0, 0, 0, 0.5)
|
||||
frame:SetBackdropBorderColor(1, 1, 1, 0.5)
|
||||
frame:SetSize(98, 98)
|
||||
if (lastBox) then
|
||||
frame:SetPoint("TOPLEFT", lastBox, "topright", 1, 0)
|
||||
else
|
||||
if (verticalLastBox) then
|
||||
frame:SetPoint("TOPLEFT", verticalLastBox, "bottomleft", 0, -1)
|
||||
verticalLastBox = frame
|
||||
else
|
||||
local x = 1 + (o - 1) * 99
|
||||
local y = -10 - (i - 1) * 99
|
||||
frame:SetPoint("TOPLEFT", container, "TOPLEFT", x, y)
|
||||
verticalLastBox = frame
|
||||
end
|
||||
end
|
||||
lastBox = frame
|
||||
end
|
||||
end
|
||||
|
||||
C_Timer.After(2, function()
|
||||
--container:SetResizeLocked(true)
|
||||
end)
|
||||
end
|
||||
|
||||
--C_Timer.After(2, function()
|
||||
-- DetailsFramework:CreateFrameContainerTest(UIParent)
|
||||
--end)
|
||||
|
||||
--[=[
|
||||
/run DetailsFramework:CreateFrameContainerTest(UIParent)
|
||||
|
||||
C_Timer.After(2, function()
|
||||
DetailsFramework:CreateFrameContainerTest(UIParent)
|
||||
end)
|
||||
|
||||
|
||||
--]=]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
|
||||
<Script file="cooltip.lua"/>
|
||||
|
||||
</Ui>
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
---@class detailsframework
|
||||
---@field OptionsFunctions df_optionsmixin
|
||||
---@field RoundedCornerPanelMixin df_roundedcornermixin
|
||||
---@field GetDefaultBackdropColor fun(self:table) : red, green, blue, alpha return a standard backdrop color
|
||||
---@field Msg fun(self:table, message:string, ...) show a message in the chat frame
|
||||
---@field MsgWarning fun(self:table, message:string, ...) show a warning message in the chat frame
|
||||
---@field CreateCloseButton fun(self:table, parent:frame, frameName:string|nil) : df_closebutton
|
||||
---@field CreateTabButton fun(self:table, parent:frame, frameName:string|nil) : df_tabbutton
|
||||
---@field CreateRoundedPanel fun(self:table, parent:frame, frameName:string|nil, optionsTable:df_roundedpanel_options|nil) : df_roundedpanel
|
||||
---@field CreateScaleBar fun(self:table, parent:frame, config:table<scale,number>) : df_scalebar
|
||||
---@field AddRoundedCornersToFrame fun(self:table, frame:frame, optionsTable:df_roundedpanel_preset|nil)
|
||||
---@field ParseColors fun(self:table, red:any, green:number|nil, blue:number|nil, alpha:number|nil) : red, green, blue, alpha
|
||||
---@field Mixin fun(self:table, target:table, ...) : table
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
<Script file="dropdown.lua"/>
|
||||
</Ui>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
|
||||
<Script file="Libs\LibStub\LibStub.lua"/>
|
||||
<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua"/>
|
||||
<Include file="Libs\LibSharedMedia-3.0\lib.xml"/>
|
||||
<Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/>
|
||||
<Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
|
||||
<Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" />
|
||||
<Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml" />
|
||||
<Include file="Libs\AceDB-3.0\AceDB-3.0.xml" />
|
||||
<Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml" />
|
||||
<Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/>
|
||||
<Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/>
|
||||
<Include file="Libs\AceComm-3.0\AceComm-3.0.xml" />
|
||||
<Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/>
|
||||
<Include file="Libs\AceSerializer-3.0\AceSerializer-3.0.xml"/>
|
||||
<Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
|
||||
<Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua"/>
|
||||
</Ui>
|
||||
@@ -1,116 +0,0 @@
|
||||
local detailsFramework = _G ["DetailsFramework"]
|
||||
if (not detailsFramework) then
|
||||
return
|
||||
end
|
||||
|
||||
local IS_WOW_PROJECT_MAINLINE = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE
|
||||
local IS_WOW_PROJECT_NOT_MAINLINE = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE
|
||||
local IS_WOW_PROJECT_CLASSIC_ERA = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC
|
||||
|
||||
detailsFramework.CastInfo = detailsFramework.CastInfo or {}
|
||||
|
||||
--NOTE: This NEEDs a chance to run, as Plater is depending on this working and LibCC is not bundled neccessarily in other addons.
|
||||
-- for classic era use LibClassicCasterino:
|
||||
|
||||
--in vanilla wow, other addons might load the framework before an addon with libCasterino loads
|
||||
--check here if libCasterino is loaded, if is, check if the framework is already using libCasterino, if not, make it use
|
||||
function detailsFramework:LoadLCC(LibCC)
|
||||
local fCast = CreateFrame("frame")
|
||||
|
||||
local getCastBar = function(unitId)
|
||||
local plateFrame = C_NamePlate.GetNamePlateForUnit (unitId)
|
||||
if (not plateFrame) then
|
||||
return
|
||||
end
|
||||
|
||||
local castBar = plateFrame.unitFrame and plateFrame.unitFrame.castBar
|
||||
if (not castBar) then
|
||||
return
|
||||
end
|
||||
|
||||
return castBar
|
||||
end
|
||||
|
||||
local triggerCastEvent = function(castBar, event, unitId, ...)
|
||||
if (castBar and castBar.OnEvent) then
|
||||
return castBar.OnEvent (castBar, event, unitId)
|
||||
end
|
||||
end
|
||||
|
||||
local funcCast = function(event, unitId, ...)
|
||||
local castBar = getCastBar (unitId)
|
||||
if (castBar) then
|
||||
return triggerCastEvent (castBar, event, unitId)
|
||||
end
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_START = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_STOP = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_DELAYED = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_FAILED = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_INTERRUPTED = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_CHANNEL_START = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_CHANNEL_UPDATE = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
fCast.UNIT_SPELLCAST_CHANNEL_STOP = function(self, event, unitId, ...)
|
||||
return triggerCastEvent (getCastBar (unitId), event, unitId)
|
||||
end
|
||||
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_START", funcCast)
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_DELAYED", funcCast) -- only for player
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_STOP", funcCast)
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_FAILED", funcCast)
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_INTERRUPTED", funcCast)
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_CHANNEL_START", funcCast)
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_CHANNEL_UPDATE", funcCast) -- only for player
|
||||
LibCC.RegisterCallback(fCast,"UNIT_SPELLCAST_CHANNEL_STOP", funcCast)
|
||||
|
||||
detailsFramework.CastInfo.UnitCastingInfo = function(unit)
|
||||
return LibCC:UnitCastingInfo (unit)
|
||||
end
|
||||
|
||||
detailsFramework.CastInfo.UnitChannelInfo = function(unit)
|
||||
return LibCC:UnitChannelInfo (unit)
|
||||
end
|
||||
end
|
||||
|
||||
if IS_WOW_PROJECT_CLASSIC_ERA then
|
||||
local LibCC = LibStub("LibClassicCasterino", true)
|
||||
if (LibCC and not _G.DetailsFrameworkLCCLoaded) then
|
||||
detailsFramework:LoadLCC(LibCC)
|
||||
_G.DetailsFrameworkLCCLoaded = true
|
||||
|
||||
elseif not LibCC then
|
||||
detailsFramework.CastInfo.UnitCastingInfo = CastingInfo
|
||||
detailsFramework.CastInfo.UnitChannelInfo = ChannelInfo
|
||||
end
|
||||
else -- end classic era
|
||||
|
||||
detailsFramework.CastInfo.UnitCastingInfo = UnitCastingInfo
|
||||
detailsFramework.CastInfo.UnitChannelInfo = UnitChannelInfo
|
||||
end
|
||||
|
||||
|
||||
if (not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
@@ -1,600 +0,0 @@
|
||||
|
||||
---@class detailsframework
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local defaultRed, defaultGreen, defaultBlue = detailsFramework:GetDefaultBackdropColor()
|
||||
--local defaultColorTable = {defaultRed, defaultGreen, defaultBlue, 1}
|
||||
local defaultColorTable = {0.98, 0.98, 0.98, 1}
|
||||
local defaultBorderColorTable = {0.1, 0.1, 0.1, 1}
|
||||
|
||||
---@type edgenames[]
|
||||
local cornerNames = {"TopLeft", "TopRight", "BottomLeft", "BottomRight"}
|
||||
|
||||
---@class blz_backdrop : table
|
||||
---@field TopLeftCorner texture
|
||||
---@field TopRightCorner texture
|
||||
---@field BottomLeftCorner texture
|
||||
---@field BottomRightCorner texture
|
||||
---@field TopEdge texture
|
||||
---@field BottomEdge texture
|
||||
---@field LeftEdge texture
|
||||
---@field RightEdge texture
|
||||
---@field Center texture
|
||||
|
||||
---@class cornertextures : table
|
||||
---@field TopLeft texture
|
||||
---@field TopRight texture
|
||||
---@field BottomLeft texture
|
||||
---@field BottomRight texture
|
||||
|
||||
---@class edgetextures : table
|
||||
---@field Top texture
|
||||
---@field Bottom texture
|
||||
---@field Left texture
|
||||
---@field Right texture
|
||||
|
||||
---@class df_roundedpanel_preset : table
|
||||
---@field border_color any
|
||||
---@field color any
|
||||
---@field roundness number
|
||||
|
||||
---@class df_roundedpanel_options : table
|
||||
---@field width number
|
||||
---@field height number
|
||||
---@field use_titlebar boolean
|
||||
---@field use_scalebar boolean
|
||||
---@field title string
|
||||
---@field scale number
|
||||
---@field roundness number
|
||||
---@field color any
|
||||
---@field border_color any
|
||||
---@field corner_texture texturepath|textureid
|
||||
|
||||
---@class df_roundedcornermixin : table
|
||||
---@field RoundedCornerConstructor fun(self:df_roundedpanel) --called from CreateRoundedPanel
|
||||
---@field SetColor fun(self:df_roundedpanel, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
||||
---@field SetBorderCornerColor fun(self:df_roundedpanel, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
||||
---@field SetRoundness fun(self:df_roundedpanel, slope: number)
|
||||
---@field GetCornerSize fun(self:df_roundedpanel) : width, height
|
||||
---@field OnSizeChanged fun(self:df_roundedpanel) --called when the frame size changes
|
||||
---@field CreateBorder fun(self:df_roundedpanel) --called from SetBorderCornerColor if the border is not created yet
|
||||
---@field CalculateBorderEdgeSize fun(self:df_roundedpanel, alignment: "vertical"|"horizontal"): number --calculate the size of the border edge texture
|
||||
---@field SetTitleBarColor fun(self:df_roundedpanel, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
||||
|
||||
---@class df_roundedpanel : frame, df_roundedcornermixin, df_optionsmixin, df_titlebar
|
||||
---@field bHasBorder boolean
|
||||
---@field bHasTitleBar boolean
|
||||
---@field options df_roundedpanel_options
|
||||
---@field cornerRoundness number
|
||||
---@field CornerTextures cornertextures
|
||||
---@field CenterTextures texture[]
|
||||
---@field BorderCornerTextures cornertextures
|
||||
---@field BorderEdgeTextures edgetextures
|
||||
---@field TitleBar df_roundedpanel
|
||||
---@field TopLeft texture corner texture
|
||||
---@field TopRight texture corner texture
|
||||
---@field BottomLeft texture corner texture
|
||||
---@field BottomRight texture corner texture
|
||||
---@field TopEdgeBorder texture border edge
|
||||
---@field BottomEdgeBorder texture border edge
|
||||
---@field LeftEdgeBorder texture border edge
|
||||
---@field RightEdgeBorder texture border edge
|
||||
---@field TopLeftBorder texture border corner
|
||||
---@field TopRightBorder texture border corner
|
||||
---@field BottomLeftBorder texture border corner
|
||||
---@field BottomRightBorder texture border corner
|
||||
---@field TopHorizontalEdge texture texture connecting the top corners
|
||||
---@field BottomHorizontalEdge texture texture connecting the bottom corners
|
||||
---@field CenterBlock texture texture connecting the bottom left of the topleft corner with the top right of the bottom right corner
|
||||
|
||||
---@param self df_roundedpanel
|
||||
---@param textures cornertextures
|
||||
---@param width number|nil
|
||||
---@param height number|nil
|
||||
---@param xOffset number|nil
|
||||
---@param yOffset number|nil
|
||||
---@param bIsBorder boolean|nil
|
||||
local setCornerPoints = function(self, textures, width, height, xOffset, yOffset, bIsBorder)
|
||||
for cornerName, thisTexture in pairs(textures) do
|
||||
thisTexture:SetSize(width or 16, height or 16)
|
||||
thisTexture:SetTexture(self.options.corner_texture)
|
||||
|
||||
--set the mask
|
||||
if (not thisTexture.MaskTexture and bIsBorder) then
|
||||
thisTexture.MaskTexture = self:CreateMaskTexture(nil, "background")
|
||||
thisTexture.MaskTexture:SetSize(74, 64)
|
||||
thisTexture:AddMaskTexture(thisTexture.MaskTexture)
|
||||
thisTexture.MaskTexture:SetTexture([[Interface\Azerite\AzeriteGoldRingRank2]]) --1940690
|
||||
--thisTexture.MaskTexture:Hide()
|
||||
end
|
||||
|
||||
xOffset = xOffset or 0
|
||||
yOffset = yOffset or 0
|
||||
|
||||
--todo: adjust the other corners setpoint offset
|
||||
--todo (done): use mask when the alpha is below 0.98, disable the mask when the alpha is above 0.98
|
||||
|
||||
if (cornerName == "TopLeft") then
|
||||
thisTexture:SetTexCoord(0, 0.5, 0, 0.5)
|
||||
thisTexture:SetPoint(cornerName, self, cornerName, -xOffset, yOffset)
|
||||
if (thisTexture.MaskTexture) then
|
||||
thisTexture.MaskTexture:SetPoint(cornerName, self, cornerName, -18-xOffset, 16+yOffset)
|
||||
end
|
||||
|
||||
elseif (cornerName == "TopRight") then
|
||||
thisTexture:SetTexCoord(0.5, 1, 0, 0.5)
|
||||
thisTexture:SetPoint(cornerName, self, cornerName, xOffset, yOffset)
|
||||
if (thisTexture.MaskTexture) then
|
||||
thisTexture.MaskTexture:SetPoint(cornerName, self, cornerName, -18+xOffset, 16+yOffset)
|
||||
end
|
||||
|
||||
elseif (cornerName == "BottomLeft") then
|
||||
thisTexture:SetTexCoord(0, 0.5, 0.5, 1)
|
||||
thisTexture:SetPoint(cornerName, self, cornerName, -xOffset, -yOffset)
|
||||
if (thisTexture.MaskTexture) then
|
||||
thisTexture.MaskTexture:SetPoint(cornerName, self, cornerName, -18-xOffset, 16-yOffset)
|
||||
end
|
||||
|
||||
elseif (cornerName == "BottomRight") then
|
||||
thisTexture:SetTexCoord(0.5, 1, 0.5, 1)
|
||||
thisTexture:SetPoint(cornerName, self, cornerName, xOffset, -yOffset)
|
||||
if (thisTexture.MaskTexture) then
|
||||
thisTexture.MaskTexture:SetPoint(cornerName, self, cornerName, -18+xOffset, 16-yOffset)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
detailsFramework.RoundedCornerPanelMixin = {
|
||||
RoundedCornerConstructor = function(self)
|
||||
self.CornerTextures = {}
|
||||
self.CenterTextures = {}
|
||||
self.BorderCornerTextures = {}
|
||||
self.BorderEdgeTextures = {}
|
||||
|
||||
self.cornerRoundness = 0
|
||||
|
||||
for i = 1, #cornerNames do
|
||||
---@type texture
|
||||
local newCornerTexture = self:CreateTexture(nil, "border", nil, 0)
|
||||
self.CornerTextures[cornerNames[i]] = newCornerTexture
|
||||
self[cornerNames[i]] = newCornerTexture
|
||||
end
|
||||
|
||||
--create the top texture which connects the top corners with a horizontal line
|
||||
---@type texture
|
||||
local topHorizontalEdge = self:CreateTexture(nil, "border", nil, 0)
|
||||
topHorizontalEdge:SetPoint("topleft", self.CornerTextures["TopLeft"], "topright", 0, 0)
|
||||
topHorizontalEdge:SetPoint("bottomleft", self.CornerTextures["TopLeft"], "bottomright", 0, 0)
|
||||
topHorizontalEdge:SetPoint("topright", self.CornerTextures["TopRight"], "topleft", 0, 0)
|
||||
topHorizontalEdge:SetPoint("bottomright", self.CornerTextures["TopRight"], "bottomleft", 0, 0)
|
||||
topHorizontalEdge:SetColorTexture(unpack(defaultColorTable))
|
||||
|
||||
--create the bottom texture which connects the bottom corners with a horizontal line
|
||||
---@type texture
|
||||
local bottomHorizontalEdge = self:CreateTexture(nil, "border", nil, 0)
|
||||
bottomHorizontalEdge:SetPoint("topleft", self.CornerTextures["BottomLeft"], "topright", 0, 0)
|
||||
bottomHorizontalEdge:SetPoint("bottomleft", self.CornerTextures["BottomLeft"], "bottomright", 0, 0)
|
||||
bottomHorizontalEdge:SetPoint("topright", self.CornerTextures["BottomRight"], "topleft", 0, 0)
|
||||
bottomHorizontalEdge:SetPoint("bottomright", self.CornerTextures["BottomRight"], "bottomleft", 0, 0)
|
||||
bottomHorizontalEdge:SetColorTexture(unpack(defaultColorTable))
|
||||
|
||||
--create the center block which connects the bottom left of the topleft corner with the top right of the bottom right corner
|
||||
---@type texture
|
||||
local centerBlock = self:CreateTexture(nil, "border", nil, 0)
|
||||
centerBlock:SetPoint("topleft", self.CornerTextures["TopLeft"], "bottomleft", 0, 0)
|
||||
centerBlock:SetPoint("bottomleft", self.CornerTextures["BottomLeft"], "topleft", 0, 0)
|
||||
centerBlock:SetPoint("topright", self.CornerTextures["BottomRight"], "topright", 0, 0)
|
||||
centerBlock:SetPoint("bottomright", self.CornerTextures["BottomRight"], "topright", 0, 0)
|
||||
centerBlock:SetColorTexture(unpack(defaultColorTable))
|
||||
|
||||
self.CenterTextures[#self.CenterTextures+1] = topHorizontalEdge
|
||||
self.CenterTextures[#self.CenterTextures+1] = bottomHorizontalEdge
|
||||
self.CenterTextures[#self.CenterTextures+1] = centerBlock
|
||||
|
||||
self.TopHorizontalEdge = topHorizontalEdge
|
||||
self.BottomHorizontalEdge = bottomHorizontalEdge
|
||||
self.CenterBlock = centerBlock
|
||||
|
||||
---@type width
|
||||
local width = self.options.width
|
||||
---@type height
|
||||
local height = self.options.height
|
||||
|
||||
self:SetSize(width, height)
|
||||
|
||||
--fill the corner and edge textures table
|
||||
setCornerPoints(self, self.CornerTextures)
|
||||
end,
|
||||
|
||||
---return the width and height of the corner textures
|
||||
---@param self df_roundedpanel
|
||||
---@return number, number
|
||||
GetCornerSize = function(self)
|
||||
return self.CornerTextures["TopLeft"]:GetSize()
|
||||
end,
|
||||
|
||||
---set how rounded the corners should be
|
||||
---@param self df_roundedpanel
|
||||
---@param roundness number
|
||||
SetRoundness = function(self, roundness)
|
||||
self.cornerRoundness = roundness
|
||||
self:OnSizeChanged()
|
||||
end,
|
||||
|
||||
---adjust the size of the corner textures and the border edge textures
|
||||
---@param self df_roundedpanel
|
||||
OnSizeChanged = function(self)
|
||||
--if the frame has a titlebar, need to adjust the size of the titlebar
|
||||
if (self.bHasTitleBar) then
|
||||
self.TitleBar:SetWidth(self:GetWidth() - 14)
|
||||
end
|
||||
|
||||
--if the frame height is below 32, need to recalculate the size of the corners
|
||||
---@type height
|
||||
local frameHeight = self:GetHeight()
|
||||
|
||||
if (frameHeight < 32) then
|
||||
local newCornerSize = frameHeight / 2
|
||||
|
||||
--set the new size of the corners on all corner textures
|
||||
for _, thisTexture in pairs(self.CornerTextures) do
|
||||
thisTexture:SetSize(newCornerSize-self.cornerRoundness, newCornerSize)
|
||||
end
|
||||
|
||||
--check if the frame has border and set the size of the border corners as well
|
||||
if (self.bHasBorder) then
|
||||
for _, thisTexture in pairs(self.BorderCornerTextures) do
|
||||
thisTexture:SetSize(newCornerSize, newCornerSize)
|
||||
end
|
||||
|
||||
--hide the left and right edges as the corner textures already is enough to fill the frame
|
||||
self.BorderEdgeTextures["Left"]:Hide()
|
||||
self.BorderEdgeTextures["Right"]:Hide()
|
||||
|
||||
local horizontalEdgesNewSize = self:CalculateBorderEdgeSize("horizontal")
|
||||
self.BorderEdgeTextures["Top"]:SetSize(horizontalEdgesNewSize, 1)
|
||||
self.BorderEdgeTextures["Bottom"]:SetSize(horizontalEdgesNewSize, 1)
|
||||
end
|
||||
|
||||
self.CenterBlock:Hide()
|
||||
else
|
||||
if (self.bHasBorder) then
|
||||
self.BorderEdgeTextures["Left"]:Show()
|
||||
self.BorderEdgeTextures["Right"]:Show()
|
||||
end
|
||||
|
||||
---@type width, height
|
||||
local cornerWidth, cornerHeight = 16, 16
|
||||
|
||||
self.CenterBlock:Show()
|
||||
|
||||
for _, thisTexture in pairs(self.CornerTextures) do
|
||||
thisTexture:SetSize(cornerWidth-self.cornerRoundness, cornerHeight-self.cornerRoundness)
|
||||
end
|
||||
|
||||
if (self.bHasBorder) then
|
||||
for _, thisTexture in pairs(self.BorderCornerTextures) do
|
||||
thisTexture:SetSize(cornerWidth-self.cornerRoundness, cornerHeight-self.cornerRoundness)
|
||||
thisTexture.MaskTexture:SetSize(74-(self.cornerRoundness*0.75), 64-self.cornerRoundness)
|
||||
end
|
||||
|
||||
local horizontalEdgesNewSize = self:CalculateBorderEdgeSize("horizontal")
|
||||
self.BorderEdgeTextures["Top"]:SetSize(horizontalEdgesNewSize, 1)
|
||||
self.BorderEdgeTextures["Bottom"]:SetSize(horizontalEdgesNewSize, 1)
|
||||
|
||||
local verticalEdgesNewSize = self:CalculateBorderEdgeSize("vertical")
|
||||
self.BorderEdgeTextures["Left"]:SetSize(1, verticalEdgesNewSize)
|
||||
self.BorderEdgeTextures["Right"]:SetSize(1, verticalEdgesNewSize)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---get the size of the edge texture
|
||||
---@param self df_roundedpanel
|
||||
---@param alignment "vertical"|"horizontal"
|
||||
---@return number edgeSize
|
||||
CalculateBorderEdgeSize = function(self, alignment)
|
||||
---@type string
|
||||
local borderCornerName = next(self.BorderCornerTextures)
|
||||
if (not borderCornerName) then
|
||||
return 0
|
||||
end
|
||||
|
||||
---@type texture
|
||||
local borderTexture = self.BorderCornerTextures[borderCornerName]
|
||||
|
||||
alignment = alignment:lower()
|
||||
|
||||
if (alignment == "vertical") then
|
||||
return self:GetHeight() - (borderTexture:GetHeight() * 2) + 2
|
||||
|
||||
elseif (alignment == "horizontal") then
|
||||
return self:GetWidth() - (borderTexture:GetHeight() * 2) + 2
|
||||
end
|
||||
|
||||
error("df_roundedpanel:CalculateBorderEdgeSize(self, alignment) alignment must be 'vertical' or 'horizontal'")
|
||||
end,
|
||||
|
||||
---@param self df_roundedpanel
|
||||
CreateBorder = function(self)
|
||||
local r, g, b, a = 0, 0, 0, 0.8
|
||||
|
||||
--create the corner edges
|
||||
for i = 1, #cornerNames do
|
||||
---@type texture
|
||||
local newBorderTexture = self:CreateTexture(nil, "background", nil, 0)
|
||||
self.BorderCornerTextures[cornerNames[i]] = newBorderTexture
|
||||
newBorderTexture:SetColorTexture(unpack(defaultColorTable))
|
||||
newBorderTexture:SetVertexColor(r, g, b, a)
|
||||
self[cornerNames[i] .. "Border"] = newBorderTexture
|
||||
end
|
||||
|
||||
setCornerPoints(self, self.BorderCornerTextures, 16, 16, 1, 1, true)
|
||||
|
||||
--create the top, left, bottom and right edges, the edge has 1pixel width and connects the corners
|
||||
---@type texture
|
||||
local topEdge = self:CreateTexture(nil, "background", nil, 0)
|
||||
topEdge:SetPoint("bottom", self, "top", 0, 0)
|
||||
self.BorderEdgeTextures["Top"] = topEdge
|
||||
|
||||
---@type texture
|
||||
local leftEdge = self:CreateTexture(nil, "background", nil, 0)
|
||||
leftEdge:SetPoint("right", self, "left", 0, 0)
|
||||
self.BorderEdgeTextures["Left"] = leftEdge
|
||||
|
||||
---@type texture
|
||||
local bottomEdge = self:CreateTexture(nil, "background", nil, 0)
|
||||
bottomEdge:SetPoint("top", self, "bottom", 0, 0)
|
||||
self.BorderEdgeTextures["Bottom"] = bottomEdge
|
||||
|
||||
---@type texture
|
||||
local rightEdge = self:CreateTexture(nil, "background", nil, 0)
|
||||
rightEdge:SetPoint("left", self, "right", 0, 0)
|
||||
self.BorderEdgeTextures["Right"] = rightEdge
|
||||
|
||||
---@type width
|
||||
local horizontalEdgeSize = self:CalculateBorderEdgeSize("horizontal")
|
||||
---@type height
|
||||
local verticalEdgeSize = self:CalculateBorderEdgeSize("vertical")
|
||||
|
||||
--set the edges size
|
||||
topEdge:SetSize(horizontalEdgeSize, 1)
|
||||
leftEdge:SetSize(1, verticalEdgeSize)
|
||||
bottomEdge:SetSize(horizontalEdgeSize, 1)
|
||||
rightEdge:SetSize(1, verticalEdgeSize)
|
||||
|
||||
for edgeName, thisTexture in pairs(self.BorderEdgeTextures) do
|
||||
---@cast thisTexture texture
|
||||
thisTexture:SetColorTexture(unpack(defaultColorTable))
|
||||
thisTexture:SetVertexColor(r, g, b, a)
|
||||
end
|
||||
|
||||
self.TopEdgeBorder = topEdge
|
||||
self.BottomEdgeBorder = bottomEdge
|
||||
self.LeftEdgeBorder = leftEdge
|
||||
self.RightEdgeBorder = rightEdge
|
||||
|
||||
self.bHasBorder = true
|
||||
end,
|
||||
|
||||
---@param self df_roundedpanel
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
SetTitleBarColor = function(self, red, green, blue, alpha)
|
||||
if (self.bHasTitleBar) then
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
self.TitleBar:SetColor(red, green, blue, alpha)
|
||||
end
|
||||
end,
|
||||
|
||||
---@param self df_roundedpanel
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
SetBorderCornerColor = function(self, red, green, blue, alpha)
|
||||
if (not self.bHasBorder) then
|
||||
self:CreateBorder()
|
||||
end
|
||||
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
|
||||
for _, thisTexture in pairs(self.BorderCornerTextures) do
|
||||
thisTexture:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
for _, thisTexture in pairs(self.BorderEdgeTextures) do
|
||||
thisTexture:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
end,
|
||||
|
||||
---@param self df_roundedpanel
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
SetColor = function(self, red, green, blue, alpha)
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
|
||||
for _, thisTexture in pairs(self.CornerTextures) do
|
||||
thisTexture:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
for _, thisTexture in pairs(self.CenterTextures) do
|
||||
thisTexture:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
if (self.bHasBorder) then
|
||||
if (alpha < 0.98) then
|
||||
--if using borders, the two border textures overlaps making the alpha be darker than it should
|
||||
for _, thisTexture in pairs(self.BorderCornerTextures) do
|
||||
thisTexture.MaskTexture:Show()
|
||||
end
|
||||
else
|
||||
for _, thisTexture in pairs(self.BorderCornerTextures) do
|
||||
thisTexture.MaskTexture:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local defaultOptions = {
|
||||
width = 200,
|
||||
height = 200,
|
||||
use_titlebar = false,
|
||||
use_scalebar = false,
|
||||
title = "",
|
||||
scale = 1,
|
||||
roundness = 0,
|
||||
color = defaultColorTable,
|
||||
border_color = defaultColorTable,
|
||||
corner_texture = [[Interface\CHARACTERFRAME\TempPortraitAlphaMaskSmall]],
|
||||
}
|
||||
|
||||
local defaultPreset = {
|
||||
border_color = {.1, .1, .1, 0.834},
|
||||
color = {defaultRed, defaultGreen, defaultBlue},
|
||||
roundness = 3,
|
||||
}
|
||||
|
||||
---create a regular panel with rounded corner
|
||||
---@param parent frame
|
||||
---@param name string|nil
|
||||
---@param optionsTable table|nil
|
||||
---@return df_roundedpanel
|
||||
function detailsFramework:CreateRoundedPanel(parent, name, optionsTable)
|
||||
---@type df_roundedpanel
|
||||
local newRoundedPanel = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
newRoundedPanel:EnableMouse(true)
|
||||
newRoundedPanel.__dftype = "df_roundedpanel"
|
||||
newRoundedPanel.__rcorners = true
|
||||
|
||||
detailsFramework:Mixin(newRoundedPanel, detailsFramework.RoundedCornerPanelMixin)
|
||||
detailsFramework:Mixin(newRoundedPanel, detailsFramework.OptionsFunctions)
|
||||
newRoundedPanel:BuildOptionsTable(defaultOptions, optionsTable or {})
|
||||
newRoundedPanel:RoundedCornerConstructor()
|
||||
newRoundedPanel:SetScript("OnSizeChanged", newRoundedPanel.OnSizeChanged)
|
||||
|
||||
if (newRoundedPanel.options.use_titlebar) then
|
||||
---@type df_roundedpanel
|
||||
local titleBar = detailsFramework:CreateRoundedPanel(newRoundedPanel, "$parentTitleBar", {height = 26})
|
||||
titleBar:SetPoint("top", newRoundedPanel, "top", 0, -7)
|
||||
newRoundedPanel.TitleBar = titleBar
|
||||
titleBar:SetRoundness(5)
|
||||
newRoundedPanel.bHasTitleBar = true
|
||||
end
|
||||
|
||||
if (newRoundedPanel.options.use_scalebar) then
|
||||
detailsFramework:CreateScaleBar(newRoundedPanel.TitleBar or newRoundedPanel, newRoundedPanel.options)
|
||||
newRoundedPanel:SetScale(newRoundedPanel.options.scale)
|
||||
end
|
||||
|
||||
newRoundedPanel:SetRoundness(newRoundedPanel.options.roundness)
|
||||
newRoundedPanel:SetColor(newRoundedPanel.options.color)
|
||||
newRoundedPanel:SetBorderCornerColor(newRoundedPanel.options.border_color)
|
||||
|
||||
return newRoundedPanel
|
||||
end
|
||||
|
||||
local applyPreset = function(frame, preset)
|
||||
if (preset.border_color) then
|
||||
frame:SetBorderCornerColor(preset.border_color)
|
||||
end
|
||||
|
||||
if (preset.color) then
|
||||
frame:SetColor(preset.color)
|
||||
end
|
||||
|
||||
if (preset.roundness) then
|
||||
frame:SetRoundness(preset.roundness)
|
||||
else
|
||||
frame:SetRoundness(1)
|
||||
end
|
||||
end
|
||||
|
||||
---set a frame to have rounded corners following the settings passed by the preset table
|
||||
---@param frame frame
|
||||
---@param preset df_roundedpanel_preset|nil
|
||||
function detailsFramework:AddRoundedCornersToFrame(frame, preset)
|
||||
frame = frame and frame.widget or frame
|
||||
assert(frame and frame.GetObjectType and frame.SetPoint, "AddRoundedCornersToFrame(frame): frame must be a frame object.")
|
||||
|
||||
if (frame.GetBackdropBorderColor) then
|
||||
local red, green, blue, alpha = frame:GetBackdropBorderColor()
|
||||
if (alpha and alpha > 0) then
|
||||
detailsFramework:MsgWarning("AddRoundedCornersToFrame() applyed to a frame with a backdrop border.")
|
||||
detailsFramework:Msg(debugstack(2, 1, 0))
|
||||
end
|
||||
end
|
||||
|
||||
---@cast frame +df_roundedcornermixin
|
||||
detailsFramework:Mixin(frame, detailsFramework.RoundedCornerPanelMixin)
|
||||
|
||||
if (not frame["BuildOptionsTable"]) then
|
||||
---@cast frame +df_optionsmixin
|
||||
detailsFramework:Mixin(frame, detailsFramework.OptionsFunctions)
|
||||
end
|
||||
|
||||
frame:BuildOptionsTable(defaultOptions, {})
|
||||
|
||||
frame.options.width = frame:GetWidth()
|
||||
frame.options.height = frame:GetHeight()
|
||||
|
||||
frame:RoundedCornerConstructor()
|
||||
frame:HookScript("OnSizeChanged", frame.OnSizeChanged)
|
||||
|
||||
frame.__rcorners = true
|
||||
|
||||
--handle preset
|
||||
if (preset and type(preset) == "table") then
|
||||
applyPreset(frame, preset)
|
||||
else
|
||||
applyPreset(frame, defaultPreset)
|
||||
end
|
||||
end
|
||||
|
||||
---test case:
|
||||
C_Timer.After(1, function() if true then return end
|
||||
local DF = DetailsFramework
|
||||
|
||||
local parent = UIParent
|
||||
local name = "NewRoundedCornerFrame"
|
||||
local optionsTable = {
|
||||
use_titlebar = true,
|
||||
use_scalebar = true,
|
||||
title = "Test",
|
||||
scale = 1.0,
|
||||
}
|
||||
|
||||
---@type df_roundedpanel
|
||||
local frame = _G[name] or DF:CreateRoundedPanel(parent, name, optionsTable)
|
||||
frame:SetSize(800, 600)
|
||||
frame:SetPoint("center", parent, "center", 0, 0)
|
||||
|
||||
frame:SetColor(.1, .1, .1, 1)
|
||||
frame:SetTitleBarColor(.2, .2, .2, .5)
|
||||
frame:SetBorderCornerColor(.2, .2, .2, .5)
|
||||
frame:SetRoundness(0)
|
||||
|
||||
local radiusSlider = DF:CreateSlider(frame, 120, 14, 0, 15, 1, frame.cornerRoundness, false, "RadiusBar", nil, nil, DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE"))
|
||||
radiusSlider:SetHook("OnValueChange", function(self, fixedValue, value)
|
||||
value = floor(value)
|
||||
if (frame.cornerRoundness == value) then
|
||||
return
|
||||
end
|
||||
frame:SetRoundness(value)
|
||||
end)
|
||||
|
||||
local radiusText = frame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
radiusText:SetText("Radius:")
|
||||
radiusText:SetPoint("bottomleft", radiusSlider.widget, "topleft", 0, 0)
|
||||
radiusSlider:SetPoint(10, -100)
|
||||
end)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,686 +0,0 @@
|
||||
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local geterrorhandler = geterrorhandler
|
||||
local wipe = wipe
|
||||
|
||||
--definitions
|
||||
|
||||
---@class df_headercolumndata : {key: string, name: string, icon: string, texcoord: table, text: string, canSort: boolean, selected: boolean, width: number, height: number, align: string, offset: number}
|
||||
|
||||
---@class df_headerchild : uiobject
|
||||
---@field FramesToAlign table
|
||||
|
||||
---@class df_headerframe : frame, df_headermixin, df_optionsmixin
|
||||
---@field columnHeadersCreated df_headercolumnframe[]
|
||||
---@field options table
|
||||
---@field HeaderTable df_headercolumndata[]
|
||||
---@field columnSelected number
|
||||
|
||||
---@class df_headermixin : table
|
||||
---@field NextHeader number
|
||||
---@field HeaderWidth number
|
||||
---@field HeaderHeight number
|
||||
---@field OnColumnSettingChangeCallback function
|
||||
---@field GetColumnWidth fun(self: df_headerframe, columnId: number) : number
|
||||
---@field SetHeaderTable fun(self: df_headerframe, table)
|
||||
---@field GetSelectedColumn fun(self: df_headerframe) : number, string, string, string
|
||||
---@field Refresh fun(self: df_headerframe)
|
||||
---@field UpdateSortArrow fun(self: df_headerframe, columnHeader: df_headercolumnframe, defaultShown: boolean|nil, defaultOrder: string|nil)
|
||||
---@field UpdateColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe, headerIndex)
|
||||
---@field ResetColumnHeaderBackdrop fun(self: df_headerframe, columnHeader: df_headercolumnframe)
|
||||
---@field SetBackdropColorForSelectedColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe)
|
||||
---@field ClearColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe)
|
||||
---@field GetNextHeader fun(self: df_headerframe) : df_headercolumnframe
|
||||
---@field SetColumnSettingChangedCallback fun(self: df_headerframe, func: function) : boolean
|
||||
|
||||
---@class df_headercolumnframe : button
|
||||
---@field Icon texture
|
||||
---@field Text fontstring
|
||||
---@field Arrow texture
|
||||
---@field Separator texture
|
||||
---@field resizerButton df_headerresizer
|
||||
---@field bIsRezising boolean
|
||||
---@field bInUse boolean
|
||||
---@field columnData table
|
||||
---@field order string
|
||||
---@field columnIndex number
|
||||
---@field columnAlign string
|
||||
---@field XPosition number
|
||||
---@field columnOffset number
|
||||
---@field key string used to sort the values
|
||||
|
||||
---@class df_headerresizer : button
|
||||
---@field texture texture
|
||||
|
||||
--mixed functions
|
||||
---@class df_headerfunctions : table
|
||||
detailsFramework.HeaderFunctions = {
|
||||
---comment
|
||||
---@param self df_headerchild
|
||||
---@param frame uiobject
|
||||
AddFrameToHeaderAlignment = function(self, frame)
|
||||
self.FramesToAlign = self.FramesToAlign or {}
|
||||
table.insert(self.FramesToAlign, frame)
|
||||
end,
|
||||
|
||||
---comment
|
||||
---@param self df_headerchild
|
||||
ResetFramesToHeaderAlignment = function(self)
|
||||
wipe(self.FramesToAlign)
|
||||
end,
|
||||
|
||||
SetFramesToHeaderAlignment = function(self, ...)
|
||||
---@cast self df_headerchild
|
||||
wipe(self.FramesToAlign)
|
||||
self.FramesToAlign = {...}
|
||||
end,
|
||||
|
||||
GetFramesFromHeaderAlignment = function(self, frame)
|
||||
return self.FramesToAlign or {}
|
||||
end,
|
||||
|
||||
---@param self uiobject
|
||||
---@param headerFrame df_headerframe
|
||||
---@param anchor string
|
||||
AlignWithHeader = function(self, headerFrame, anchor)
|
||||
local columnHeaderFrames = headerFrame.columnHeadersCreated
|
||||
anchor = anchor or "topleft"
|
||||
|
||||
---@cast self df_headerchild
|
||||
|
||||
for i = 1, #self.FramesToAlign do
|
||||
---@type uiobject
|
||||
local uiObject = self.FramesToAlign[i]
|
||||
uiObject:ClearAllPoints()
|
||||
|
||||
---@type df_headercolumnframe
|
||||
local columnHeader = columnHeaderFrames[i]
|
||||
if (columnHeader) then
|
||||
local offset = 0
|
||||
|
||||
if (columnHeader.columnAlign == "right") then
|
||||
offset = columnHeader:GetWidth()
|
||||
end
|
||||
|
||||
if (uiObject:GetObjectType() == "FontString") then
|
||||
---@cast uiObject fontstring
|
||||
if (columnHeader.columnAlign == "right") then
|
||||
uiObject:SetJustifyH("right")
|
||||
elseif (columnHeader.columnAlign == "left") then
|
||||
uiObject:SetJustifyH("left")
|
||||
elseif (columnHeader.columnAlign == "center") then
|
||||
uiObject:SetJustifyH("center")
|
||||
end
|
||||
end
|
||||
|
||||
uiObject:SetPoint(columnHeader.columnAlign, self, anchor, columnHeader.XPosition + columnHeader.columnOffset + offset, 0)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---comment
|
||||
---@param columnHeader df_headercolumnframe
|
||||
---@param buttonClicked string
|
||||
OnClick = function(columnHeader, buttonClicked)
|
||||
--get the header main frame
|
||||
local headerFrame = columnHeader:GetParent()
|
||||
---@cast headerFrame df_headerframe
|
||||
|
||||
--if this header does not have a clickable header, just ignore
|
||||
if (not headerFrame.columnSelected) then
|
||||
return
|
||||
end
|
||||
|
||||
--check if this column has 'canSort' key, otherwise ignore the click
|
||||
if (not columnHeader.columnData.canSort) then
|
||||
return
|
||||
end
|
||||
|
||||
--get the latest column header selected
|
||||
---@type df_headercolumnframe
|
||||
local previousColumnHeader = headerFrame.columnHeadersCreated[headerFrame.columnSelected]
|
||||
previousColumnHeader.Arrow:Hide()
|
||||
headerFrame:ResetColumnHeaderBackdrop(previousColumnHeader)
|
||||
headerFrame:SetBackdropColorForSelectedColumnHeader(columnHeader)
|
||||
|
||||
if (headerFrame.columnSelected == columnHeader.columnIndex) then
|
||||
columnHeader.order = columnHeader.order ~= "ASC" and "ASC" or "DESC"
|
||||
end
|
||||
headerFrame.columnOrder = columnHeader.order
|
||||
|
||||
--set the new column header selected
|
||||
headerFrame.columnSelected = columnHeader.columnIndex
|
||||
|
||||
headerFrame:UpdateSortArrow(columnHeader)
|
||||
|
||||
if (headerFrame.options.header_click_callback) then
|
||||
--callback with the main header frame, column header, column index and column order as payload
|
||||
local okay, errortext = pcall(headerFrame.options.header_click_callback, headerFrame, columnHeader, columnHeader.columnIndex, columnHeader.order)
|
||||
if (not okay) then
|
||||
print("DF: Header onClick callback error:", errortext)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---comment
|
||||
---@param self button
|
||||
---@param buttonClicked string
|
||||
OnMouseDown = function(self, buttonClicked)
|
||||
if (buttonClicked == "LeftButton") then
|
||||
|
||||
end
|
||||
end,
|
||||
|
||||
---comment
|
||||
---@param self button
|
||||
---@param buttonClicked string
|
||||
OnMouseUp = function(self, buttonClicked)
|
||||
if (buttonClicked == "LeftButton") then
|
||||
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---@class df_headermixin : table
|
||||
detailsFramework.HeaderMixin = {
|
||||
---@param self df_headerframe
|
||||
---@param columnId number
|
||||
---@return number
|
||||
GetColumnWidth = function(self, columnId)
|
||||
return self.HeaderTable[columnId].width
|
||||
end,
|
||||
|
||||
---@param self df_headerframe
|
||||
---@param newTable table
|
||||
SetHeaderTable = function(self, newTable)
|
||||
self.columnHeadersCreated = self.columnHeadersCreated or {}
|
||||
self.HeaderTable = newTable
|
||||
self.NextHeader = 1
|
||||
self.HeaderWidth = 0
|
||||
self.HeaderHeight = 0
|
||||
self:Refresh()
|
||||
end,
|
||||
|
||||
---@param self df_headerframe
|
||||
---@param func function
|
||||
---@return boolean
|
||||
SetColumnSettingChangedCallback = function(self, func)
|
||||
if (type(func) ~= "function") then
|
||||
self.OnColumnSettingChangeCallback = nil
|
||||
return false
|
||||
end
|
||||
self.OnColumnSettingChangeCallback = func
|
||||
return true
|
||||
end,
|
||||
|
||||
--return which header is current selected and the the order ASC DESC
|
||||
---@param self df_headerframe
|
||||
---@return number, string, string, string
|
||||
GetSelectedColumn = function(self)
|
||||
---@type number
|
||||
local columnSelected = self.columnSelected
|
||||
---@type df_headercolumnframe
|
||||
local columnHeader = self.columnHeadersCreated[columnSelected or 1]
|
||||
return columnSelected, columnHeader.order, columnHeader.key, columnHeader.columnData.name
|
||||
end,
|
||||
|
||||
--clean up and rebuild the header following the header options
|
||||
--@self: main header frame
|
||||
---@param self df_headerframe
|
||||
Refresh = function(self)
|
||||
--refresh background frame
|
||||
self:SetBackdrop(self.options.backdrop)
|
||||
self:SetBackdropColor(unpack(self.options.backdrop_color))
|
||||
self:SetBackdropBorderColor(unpack(self.options.backdrop_border_color))
|
||||
|
||||
--reset all header frames
|
||||
for i = 1, #self.columnHeadersCreated do
|
||||
local columnHeader = self.columnHeadersCreated[i]
|
||||
columnHeader.bInUse = false
|
||||
columnHeader:Hide()
|
||||
end
|
||||
|
||||
local previousColumnHeader
|
||||
local growDirection = string.lower(self.options.grow_direction)
|
||||
|
||||
--amount of headers to be updated
|
||||
local headerSize = #self.HeaderTable
|
||||
|
||||
--update header frames
|
||||
for i = 1, headerSize do
|
||||
--get the header button, a new one is created if it doesn't exists yet
|
||||
local columnHeader = self:GetNextHeader()
|
||||
self:UpdateColumnHeader(columnHeader, i)
|
||||
|
||||
--grow direction
|
||||
if (not previousColumnHeader) then
|
||||
columnHeader:SetPoint("topleft", self, "topleft", 0, 0)
|
||||
|
||||
if (growDirection == "right") then
|
||||
if (self.options.use_line_separators) then
|
||||
columnHeader.Separator:Show()
|
||||
columnHeader.Separator:SetWidth(self.options.line_separator_width)
|
||||
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
|
||||
|
||||
columnHeader.Separator:ClearAllPoints()
|
||||
if (self.options.line_separator_gap_align) then
|
||||
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
|
||||
else
|
||||
columnHeader.Separator:SetPoint("topright", columnHeader, "topright", 0, 0)
|
||||
end
|
||||
columnHeader.Separator:SetHeight(self.options.line_separator_height)
|
||||
end
|
||||
end
|
||||
else
|
||||
if (growDirection == "right") then
|
||||
columnHeader:SetPoint("topleft", previousColumnHeader, "topright", self.options.padding, 0)
|
||||
|
||||
if (self.options.use_line_separators) then
|
||||
columnHeader.Separator:Show()
|
||||
columnHeader.Separator:SetWidth(self.options.line_separator_width)
|
||||
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
|
||||
|
||||
columnHeader.Separator:ClearAllPoints()
|
||||
if (self.options.line_separator_gap_align) then
|
||||
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
|
||||
else
|
||||
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
|
||||
end
|
||||
columnHeader.Separator:SetHeight(self.options.line_separator_height)
|
||||
|
||||
if (headerSize == i) then
|
||||
columnHeader.Separator:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
elseif (growDirection == "left") then
|
||||
columnHeader:SetPoint("topright", previousColumnHeader, "topleft", -self.options.padding, 0)
|
||||
|
||||
elseif (growDirection == "bottom") then
|
||||
columnHeader:SetPoint("topleft", previousColumnHeader, "bottomleft", 0, -self.options.padding)
|
||||
|
||||
elseif (growDirection == "top") then
|
||||
columnHeader:SetPoint("bottomleft", previousColumnHeader, "topleft", 0, self.options.padding)
|
||||
end
|
||||
end
|
||||
|
||||
previousColumnHeader = columnHeader
|
||||
end
|
||||
|
||||
self:SetSize(self.HeaderWidth, self.HeaderHeight)
|
||||
end,
|
||||
|
||||
---@param self df_headerframe
|
||||
---@param columnHeader df_headercolumnframe
|
||||
---@param defaultShown boolean
|
||||
---@param defaultOrder string
|
||||
UpdateSortArrow = function(self, columnHeader, defaultShown, defaultOrder)
|
||||
local options = self.options
|
||||
local order = defaultOrder or columnHeader.order
|
||||
local arrowIcon = columnHeader.Arrow
|
||||
|
||||
if (type(defaultShown) ~= "boolean") then
|
||||
arrowIcon:Show()
|
||||
else
|
||||
arrowIcon:SetShown(defaultShown)
|
||||
if (defaultShown) then
|
||||
self:SetBackdropColorForSelectedColumnHeader(columnHeader)
|
||||
end
|
||||
end
|
||||
|
||||
arrowIcon:SetAlpha(options.arrow_alpha)
|
||||
|
||||
if (order == "ASC") then
|
||||
arrowIcon:SetTexture(options.arrow_up_texture)
|
||||
arrowIcon:SetTexCoord(unpack(options.arrow_up_texture_coords))
|
||||
arrowIcon:SetSize(unpack(options.arrow_up_size))
|
||||
|
||||
elseif (order == "DESC") then
|
||||
arrowIcon:SetTexture(options.arrow_down_texture)
|
||||
arrowIcon:SetTexCoord(unpack(options.arrow_down_texture_coords))
|
||||
arrowIcon:SetSize(unpack(options.arrow_down_size))
|
||||
end
|
||||
end,
|
||||
|
||||
---@param self df_headerframe
|
||||
---@param columnHeader df_headercolumnframe
|
||||
---@param headerIndex number
|
||||
UpdateColumnHeader = function(self, columnHeader, headerIndex)
|
||||
--this is the data to update the columnHeader
|
||||
local columnData = self.HeaderTable[headerIndex]
|
||||
columnHeader.key = columnData.key or "total"
|
||||
|
||||
if (columnData.icon) then
|
||||
columnHeader.Icon:SetTexture(columnData.icon)
|
||||
|
||||
if (columnData.texcoord) then
|
||||
columnHeader.Icon:SetTexCoord(unpack(columnData.texcoord))
|
||||
else
|
||||
columnHeader.Icon:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
|
||||
columnHeader.Icon:SetPoint("left", columnHeader, "left", self.options.padding, 0)
|
||||
columnHeader.Icon:Show()
|
||||
end
|
||||
|
||||
if (columnData.text) then
|
||||
columnHeader.Text:SetText(columnData.text)
|
||||
|
||||
--text options
|
||||
detailsFramework:SetFontColor(columnHeader.Text, self.options.text_color)
|
||||
detailsFramework:SetFontSize(columnHeader.Text, self.options.text_size)
|
||||
detailsFramework:SetFontOutline(columnHeader.Text, self.options.text_shadow)
|
||||
|
||||
--point
|
||||
if (not columnData.icon) then
|
||||
columnHeader.Text:SetPoint("left", columnHeader, "left", self.options.padding, 0)
|
||||
else
|
||||
columnHeader.Text:SetPoint("left", columnHeader.Icon, "right", self.options.padding, 0)
|
||||
end
|
||||
|
||||
columnHeader.Text:Show()
|
||||
end
|
||||
|
||||
--column header index
|
||||
columnHeader.columnIndex = headerIndex
|
||||
|
||||
if (columnData.canSort) then
|
||||
columnHeader.order = "DESC"
|
||||
columnHeader.Arrow:SetTexture(self.options.arrow_up_texture)
|
||||
else
|
||||
columnHeader.Arrow:Hide()
|
||||
end
|
||||
|
||||
if (columnData.selected) then
|
||||
columnHeader.Arrow:Show()
|
||||
columnHeader.Arrow:SetAlpha(.843)
|
||||
self:UpdateSortArrow(columnHeader, true, columnHeader.order)
|
||||
self.columnSelected = headerIndex
|
||||
else
|
||||
if (columnData.canSort) then
|
||||
self:UpdateSortArrow(columnHeader, false, columnHeader.order)
|
||||
end
|
||||
end
|
||||
|
||||
--size
|
||||
if (columnData.width) then
|
||||
columnHeader:SetWidth(columnData.width)
|
||||
end
|
||||
if (columnData.height) then
|
||||
columnHeader:SetHeight(columnData.height)
|
||||
end
|
||||
|
||||
columnHeader.XPosition = self.HeaderWidth -- + self.options.padding
|
||||
columnHeader.YPosition = self.HeaderHeight -- + self.options.padding
|
||||
|
||||
columnHeader.columnAlign = columnData.align or "left"
|
||||
columnHeader.columnOffset = columnData.offset or 0
|
||||
|
||||
--add the header piece size to the total header size
|
||||
local growDirection = string.lower(self.options.grow_direction)
|
||||
|
||||
if (growDirection == "right" or growDirection == "left") then
|
||||
self.HeaderWidth = self.HeaderWidth + columnHeader:GetWidth() + self.options.padding
|
||||
self.HeaderHeight = math.max(self.HeaderHeight, columnHeader:GetHeight())
|
||||
|
||||
elseif (growDirection == "top" or growDirection == "bottom") then
|
||||
self.HeaderWidth = math.max(self.HeaderWidth, columnHeader:GetWidth())
|
||||
self.HeaderHeight = self.HeaderHeight + columnHeader:GetHeight() + self.options.padding
|
||||
end
|
||||
|
||||
local bShowColumnHeaderReziser = self.options.reziser_shown
|
||||
if (bShowColumnHeaderReziser) then
|
||||
local resizerButton = columnHeader.resizerButton
|
||||
resizerButton:Show()
|
||||
resizerButton.texture:SetVertexColor(unpack(self.options.reziser_color))
|
||||
resizerButton:SetWidth(self.options.reziser_width)
|
||||
resizerButton:SetHeight(columnHeader:GetHeight())
|
||||
else
|
||||
columnHeader.resizerButton:Hide()
|
||||
end
|
||||
|
||||
columnHeader:Show()
|
||||
columnHeader.bInUse = true
|
||||
columnHeader.columnData = columnData
|
||||
end,
|
||||
|
||||
---reset column header backdrop
|
||||
---@param self df_headerframe
|
||||
---@param columnHeader df_headercolumnframe
|
||||
ResetColumnHeaderBackdrop = function(self, columnHeader)
|
||||
columnHeader:SetBackdrop(self.options.header_backdrop)
|
||||
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color))
|
||||
columnHeader:SetBackdropBorderColor(unpack(self.options.header_backdrop_border_color))
|
||||
end,
|
||||
|
||||
---@param self df_headerframe
|
||||
---@param columnHeader df_headercolumnframe
|
||||
SetBackdropColorForSelectedColumnHeader = function(self, columnHeader)
|
||||
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color_selected))
|
||||
end,
|
||||
|
||||
---clear the column header
|
||||
---@param self df_headerframe
|
||||
---@param columnHeader df_headercolumnframe
|
||||
ClearColumnHeader = function(self, columnHeader)
|
||||
columnHeader:SetSize(self.options.header_width, self.options.header_height)
|
||||
self:ResetColumnHeaderBackdrop(columnHeader)
|
||||
|
||||
columnHeader:ClearAllPoints()
|
||||
|
||||
columnHeader.Icon:SetTexture("")
|
||||
columnHeader.Icon:Hide()
|
||||
columnHeader.Text:SetText("")
|
||||
columnHeader.Text:Hide()
|
||||
end,
|
||||
|
||||
---get the next column header, create one if doesn't exists
|
||||
---@param self df_headerframe
|
||||
GetNextHeader = function(self)
|
||||
local nextHeader = self.NextHeader
|
||||
local columnHeader = self.columnHeadersCreated[nextHeader]
|
||||
|
||||
if (not columnHeader) then
|
||||
--create a new column header
|
||||
---@type df_headercolumnframe
|
||||
columnHeader = CreateFrame("button", "$parentHeaderIndex" .. nextHeader, self, "BackdropTemplate")
|
||||
columnHeader:SetScript("OnClick", detailsFramework.HeaderFunctions.OnClick)
|
||||
columnHeader:SetMovable(true)
|
||||
columnHeader:SetResizable(true)
|
||||
|
||||
--header icon
|
||||
detailsFramework:CreateImage(columnHeader, "", self.options.header_height, self.options.header_height, "ARTWORK", nil, "Icon", "$parentIcon")
|
||||
--header separator
|
||||
detailsFramework:CreateImage(columnHeader, "", 1, 1, "ARTWORK", nil, "Separator", "$parentSeparator")
|
||||
--header name text
|
||||
detailsFramework:CreateLabel(columnHeader, "", self.options.text_size, self.options.text_color, "GameFontNormal", "Text", "$parentText", "ARTWORK")
|
||||
--header selected and order icon
|
||||
detailsFramework:CreateImage(columnHeader, self.options.arrow_up_texture, 12, 12, "ARTWORK", nil, "Arrow", "$parentArrow")
|
||||
|
||||
---rezise button
|
||||
---@type df_headerresizer
|
||||
local resizerButton = CreateFrame("button", "$parentResizer", columnHeader)
|
||||
resizerButton:SetWidth(4)
|
||||
resizerButton:SetFrameLevel(columnHeader:GetFrameLevel()+2)
|
||||
resizerButton:SetPoint("topright", columnHeader, "topright", -1, -1)
|
||||
resizerButton:SetPoint("bottomright", columnHeader, "bottomright", -1, 1)
|
||||
resizerButton:EnableMouse(true)
|
||||
resizerButton:RegisterForClicks("LeftButtonDown", "LeftButtonUp")
|
||||
columnHeader.resizerButton = resizerButton
|
||||
|
||||
resizerButton:SetScript("OnEnter", function()
|
||||
resizerButton.texture:SetVertexColor(1, 1, 1, 0.9)
|
||||
end)
|
||||
|
||||
resizerButton:SetScript("OnLeave", function()
|
||||
resizerButton.texture:SetVertexColor(unpack(self.options.reziser_color))
|
||||
end)
|
||||
|
||||
resizerButton:SetScript("OnMouseDown", function() --move this to a single function
|
||||
if (not columnHeader.bIsRezising) then
|
||||
--get the string length to know the min size
|
||||
local textLength = columnHeader.Text:GetStringWidth() + 6
|
||||
columnHeader:SetResizeBounds(math.max(textLength, self.options.reziser_min_width), columnHeader:GetHeight(), self.options.reziser_max_width, columnHeader:GetHeight())
|
||||
columnHeader.bIsRezising = true
|
||||
columnHeader:StartSizing("right")
|
||||
end
|
||||
end)
|
||||
|
||||
resizerButton:SetScript("OnMouseUp", function()
|
||||
if (columnHeader.bIsRezising) then
|
||||
columnHeader.bIsRezising = false
|
||||
columnHeader:StopMovingOrSizing()
|
||||
|
||||
--callback or modify into a passed by table?
|
||||
if (self.OnColumnSettingChangeCallback) then --need to get the header name
|
||||
local columnName = columnHeader.columnData.name
|
||||
xpcall(self.OnColumnSettingChangeCallback, geterrorhandler(), self, "width", columnName, columnHeader:GetWidth())
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
resizerButton:SetScript("OnHide", function()
|
||||
if (columnHeader.bIsRezising) then
|
||||
columnHeader:StopMovingOrSizing()
|
||||
columnHeader.bIsRezising = false
|
||||
end
|
||||
end)
|
||||
|
||||
resizerButton.texture = resizerButton:CreateTexture(nil, "overlay")
|
||||
resizerButton.texture:SetAllPoints()
|
||||
resizerButton.texture:SetColorTexture(1, 1, 1, 1)
|
||||
|
||||
local xOffset = self.options.reziser_shown and -5 or -1
|
||||
columnHeader.Arrow:SetPoint("right", columnHeader, "right", xOffset, 0)
|
||||
|
||||
columnHeader.Separator:Hide()
|
||||
columnHeader.Arrow:Hide()
|
||||
|
||||
self:UpdateSortArrow(columnHeader, false, "DESC")
|
||||
|
||||
table.insert(self.columnHeadersCreated, columnHeader)
|
||||
columnHeader = columnHeader
|
||||
end
|
||||
|
||||
self:ClearColumnHeader(columnHeader)
|
||||
self.NextHeader = self.NextHeader + 1
|
||||
return columnHeader
|
||||
end,
|
||||
|
||||
---return a header button by passing its name (.name on the column table)
|
||||
---@param self df_headerframe
|
||||
---@param columnName string
|
||||
---@return df_headercolumnframe|nil
|
||||
GetHeaderColumnByName = function(self, columnName)
|
||||
for _, headerColumnFrame in ipairs(self.columnHeadersCreated) do
|
||||
if (headerColumnFrame.columnData.name == columnName) then
|
||||
return headerColumnFrame
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
NextHeader = 1,
|
||||
HeaderWidth = 0,
|
||||
HeaderHeight = 0,
|
||||
}
|
||||
|
||||
--default options
|
||||
local default_header_options = {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdrop_color = {0, 0, 0, 0.2},
|
||||
backdrop_border_color = {0.1, 0.1, 0.1, .2},
|
||||
|
||||
text_color = {1, 1, 1, 1},
|
||||
text_size = 10,
|
||||
text_shadow = false,
|
||||
grow_direction = "RIGHT",
|
||||
padding = 2,
|
||||
|
||||
reziser_shown = false, --make sure to set the callback function with: header:SetOnColumnResizeScript(callbackFunction)
|
||||
reziser_width = 2,
|
||||
reziser_color = {1, 0.6, 0, 0.6},
|
||||
reziser_min_width = 16,
|
||||
reziser_max_width = 200,
|
||||
|
||||
--each piece of the header
|
||||
header_backdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
header_backdrop_color = {0, 0, 0, 0.5},
|
||||
header_backdrop_color_selected = {0.3, 0.3, 0.3, 0.5},
|
||||
header_backdrop_border_color = {0, 0, 0, 0},
|
||||
header_width = 120,
|
||||
header_height = 20,
|
||||
|
||||
arrow_up_texture = [[Interface\Buttons\Arrow-Up-Down]],
|
||||
arrow_up_texture_coords = {0, 1, 6/16, 1},
|
||||
arrow_up_size = {12, 11},
|
||||
arrow_down_texture = [[Interface\Buttons\Arrow-Down-Down]],
|
||||
arrow_down_texture_coords = {0, 1, 0, 11/16},
|
||||
arrow_down_size = {12, 11},
|
||||
arrow_alpha = 0.659,
|
||||
|
||||
use_line_separators = false,
|
||||
line_separator_color = {.1, .1, .1, .6},
|
||||
line_separator_width = 1,
|
||||
line_separator_height = 200,
|
||||
line_separator_gap_align = false,
|
||||
}
|
||||
|
||||
---create a df_headerframe, alias 'header'.
|
||||
---a header is a frame that can hold multiple columns which are also frames, each column is a df_headercolumnframe, these columns are arranged in horizontal form.
|
||||
---a header is used to organize columns giving them a name/title, a way to sort and align them.
|
||||
---each column is placed on the right side of the previous column.
|
||||
---@param parent frame
|
||||
---@param headerTable table
|
||||
---@param options table|nil
|
||||
---@param frameName string|nil
|
||||
---@return df_headerframe
|
||||
function detailsFramework:CreateHeader(parent, headerTable, options, frameName)
|
||||
---create the header frame which is returned by this function
|
||||
---@type df_headerframe
|
||||
local newHeader = CreateFrame("frame", frameName or "$parentHeaderLine", parent, "BackdropTemplate")
|
||||
|
||||
detailsFramework:Mixin(newHeader, detailsFramework.OptionsFunctions)
|
||||
detailsFramework:Mixin(newHeader, detailsFramework.HeaderMixin)
|
||||
|
||||
newHeader:BuildOptionsTable(default_header_options, options)
|
||||
|
||||
--set the backdrop and backdrop color following the values in the options table
|
||||
newHeader:SetBackdrop(newHeader.options.backdrop)
|
||||
newHeader:SetBackdropColor(unpack(newHeader.options.backdrop_color))
|
||||
newHeader:SetBackdropBorderColor(unpack(newHeader.options.backdrop_border_color))
|
||||
|
||||
newHeader:SetHeaderTable(headerTable)
|
||||
|
||||
return newHeader
|
||||
end
|
||||
|
||||
|
||||
--[=[example:
|
||||
C_Timer.After(1, function()
|
||||
|
||||
|
||||
local parent = UIParent
|
||||
|
||||
--declare the columns the headerFrame will have
|
||||
---@type df_headercolumndata[]
|
||||
local headerTable = {
|
||||
{name = "playername", text = "Player Name", width = 120, align = "left", canSort = true},
|
||||
{name = "damage", text = "Damage Done", width = 80, align = "right", canSort = true},
|
||||
{name = "points", text = "Total Points", width = 80, align = "right", canSort = false},
|
||||
}
|
||||
local frameName = "MyAddOnOptionsFrame"
|
||||
local options = {}
|
||||
|
||||
local headerFrame = DetailsFramework:CreateHeader(parent, headerTable, options, frameName)
|
||||
headerFrame:SetPoint("center", parent, "center", 10, -10)
|
||||
|
||||
|
||||
end)
|
||||
--]=]
|
||||
@@ -1,123 +0,0 @@
|
||||
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local rawset = rawset --lua local
|
||||
local rawget = rawget --lua local
|
||||
|
||||
local APIHelpFunctions = false
|
||||
local HelpMetaFunctions = {}
|
||||
|
||||
local get_members_function_index = {}
|
||||
|
||||
HelpMetaFunctions.__index = function(_table, _member_requested)
|
||||
|
||||
local func = get_members_function_index [_member_requested]
|
||||
if (func) then
|
||||
return func (_table, _member_requested)
|
||||
end
|
||||
|
||||
local fromMe = rawget (_table, _member_requested)
|
||||
if (fromMe) then
|
||||
return fromMe
|
||||
end
|
||||
|
||||
return HelpMetaFunctions [_member_requested]
|
||||
end
|
||||
|
||||
local set_members_function_index = {}
|
||||
|
||||
HelpMetaFunctions.__newindex = function(_table, _key, _value)
|
||||
local func = set_members_function_index [_key]
|
||||
if (func) then
|
||||
return func (_table, _value)
|
||||
else
|
||||
return rawset (_table, _key, _value)
|
||||
end
|
||||
end
|
||||
|
||||
function HelpMetaFunctions:AddHelp (width, height, x, y, buttonX, buttonY, text, anchor)
|
||||
self.helpTable [#self.helpTable + 1] = {
|
||||
HighLightBox = {x = x, y = y, width = width, height = height},
|
||||
ButtonPos = { x = buttonX, y = buttonY},
|
||||
ToolTipDir = anchor or "RIGHT",
|
||||
ToolTipText = text
|
||||
}
|
||||
end
|
||||
|
||||
function HelpMetaFunctions:SetPoint(v1, v2, v3, v4, v5)
|
||||
v1, v2, v3, v4, v5 = DF:CheckPoints (v1, v2, v3, v4, v5, self)
|
||||
if (not v1) then
|
||||
print("Invalid parameter for SetPoint")
|
||||
return
|
||||
end
|
||||
return self.widget:SetPoint(v1, v2, v3, v4, v5)
|
||||
end
|
||||
|
||||
function HelpMetaFunctions:ShowHelp()
|
||||
if (not HelpPlate_IsShowing (self.helpTable)) then
|
||||
HelpPlate_Show (self.helpTable, self.frame, self.button, true)
|
||||
else
|
||||
HelpPlate_Hide (true)
|
||||
end
|
||||
end
|
||||
|
||||
local nameCounter = 1
|
||||
function DF:NewHelp (parent, width, height, x, y, buttonWidth, buttonHeight, name)
|
||||
|
||||
local help = {}
|
||||
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
|
||||
local helpButton = CreateFrame("button", name or "DetailsFrameworkHelpButton"..nameCounter, parent, "MainHelpPlateButton")
|
||||
nameCounter = nameCounter + 1
|
||||
|
||||
if (not APIHelpFunctions) then
|
||||
APIHelpFunctions = true
|
||||
local idx = getmetatable(helpButton).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not HelpMetaFunctions [funcName]) then
|
||||
HelpMetaFunctions [funcName] = function(object, ...)
|
||||
local x = loadstring ( "return _G."..object.button:GetName()..":"..funcName.."(...)")
|
||||
return x (...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (buttonWidth and buttonHeight) then
|
||||
helpButton:SetWidth(buttonWidth)
|
||||
helpButton:SetHeight(buttonHeight)
|
||||
helpButton.I:SetWidth(buttonWidth*0.8)
|
||||
helpButton.I:SetHeight(buttonHeight*0.8)
|
||||
helpButton.Ring:SetWidth(buttonWidth)
|
||||
helpButton.Ring:SetHeight(buttonHeight)
|
||||
helpButton.Ring:SetPoint("center", buttonWidth*.2, -buttonWidth*.2)
|
||||
end
|
||||
|
||||
help.helpTable = {
|
||||
FramePos = {x = x, y = y},
|
||||
FrameSize = {width = width, height = height}
|
||||
}
|
||||
|
||||
help.frame = parent
|
||||
help.button = helpButton
|
||||
help.widget = helpButton
|
||||
help.I = helpButton.I
|
||||
help.Ring = helpButton.Ring
|
||||
|
||||
helpButton:SetScript("OnClick", function()
|
||||
help:ShowHelp()
|
||||
end)
|
||||
|
||||
setmetatable(help, HelpMetaFunctions)
|
||||
|
||||
return help
|
||||
|
||||
end
|
||||
@@ -1,487 +0,0 @@
|
||||
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local PixelUtil = PixelUtil
|
||||
|
||||
detailsFramework.IconMixin = {
|
||||
---create a new icon frame
|
||||
---@param self frame the parent frame
|
||||
---@param iconName string the name of the icon frame
|
||||
---@return frame
|
||||
CreateIcon = function(self, iconName)
|
||||
local iconFrame = CreateFrame("frame", iconName, self, "BackdropTemplate")
|
||||
|
||||
iconFrame.Texture = iconFrame:CreateTexture(nil, "artwork")
|
||||
PixelUtil.SetPoint(iconFrame.Texture, "topleft", iconFrame, "topleft", 1, -1)
|
||||
PixelUtil.SetPoint(iconFrame.Texture, "bottomright", iconFrame, "bottomright", -1, 1)
|
||||
|
||||
iconFrame.Border = iconFrame:CreateTexture(nil, "background")
|
||||
iconFrame.Border:SetAllPoints()
|
||||
iconFrame.Border:SetColorTexture(0, 0, 0)
|
||||
|
||||
iconFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
iconFrame:SetBackdropBorderColor(0, 0, 0, 0)
|
||||
iconFrame:EnableMouse(false)
|
||||
|
||||
local cooldownFrame = CreateFrame("cooldown", "$parentCooldown", iconFrame, "CooldownFrameTemplate, BackdropTemplate")
|
||||
cooldownFrame:SetAllPoints()
|
||||
cooldownFrame:EnableMouse(false)
|
||||
cooldownFrame:SetFrameLevel(iconFrame:GetFrameLevel()+1)
|
||||
iconFrame.Cooldown = cooldownFrame
|
||||
|
||||
iconFrame.CountdownText = cooldownFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
iconFrame.CountdownText:SetPoint("center", iconFrame, "center", 0, 0)
|
||||
iconFrame.CountdownText:Hide()
|
||||
|
||||
iconFrame.StackText = iconFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
iconFrame.StackText:SetPoint("center", iconFrame, "bottomright", 0, 0)
|
||||
iconFrame.StackText:Hide()
|
||||
|
||||
iconFrame.Desc = iconFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
iconFrame.Desc:SetPoint("bottom", iconFrame, "top", 0, 2)
|
||||
iconFrame.Desc:Hide()
|
||||
|
||||
return iconFrame
|
||||
end,
|
||||
|
||||
GetIcon = function(self)
|
||||
local iconFrame = self.IconPool[self.NextIcon]
|
||||
|
||||
if (not iconFrame) then
|
||||
local newIconFrame = self:CreateIcon("$parentIcon" .. self.NextIcon)
|
||||
newIconFrame.parentIconRow = self
|
||||
newIconFrame.Cooldown:SetHideCountdownNumbers(self.options.surpress_blizzard_cd_timer)
|
||||
newIconFrame.Cooldown.noCooldownCount = self.options.surpress_tulla_omni_cc
|
||||
|
||||
newIconFrame.CountdownText:ClearAllPoints()
|
||||
newIconFrame.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)
|
||||
newIconFrame.StackText:ClearAllPoints()
|
||||
newIconFrame.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)
|
||||
newIconFrame.Desc:ClearAllPoints()
|
||||
newIconFrame.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)
|
||||
|
||||
self.IconPool[self.NextIcon] = newIconFrame
|
||||
iconFrame = newIconFrame
|
||||
end
|
||||
|
||||
iconFrame:ClearAllPoints()
|
||||
|
||||
local anchor = self.options.anchor
|
||||
local anchorTo = self.NextIcon == 1 and self or self.IconPool[self.NextIcon - 1]
|
||||
local xPadding = self.NextIcon == 1 and self.options.left_padding or self.options.icon_padding or 1
|
||||
local growDirection = self.options.grow_direction
|
||||
|
||||
if (growDirection == 1) then --grow to right
|
||||
if (self.NextIcon == 1) then
|
||||
PixelUtil.SetPoint(iconFrame, "left", anchorTo, "left", xPadding, 0)
|
||||
else
|
||||
PixelUtil.SetPoint(iconFrame, "left", anchorTo, "right", xPadding, 0)
|
||||
end
|
||||
|
||||
elseif (growDirection == 2) then --grow to left
|
||||
if (self.NextIcon == 1) then
|
||||
PixelUtil.SetPoint(iconFrame, "right", anchorTo, "right", xPadding, 0)
|
||||
else
|
||||
PixelUtil.SetPoint(iconFrame, "right", anchorTo, "left", xPadding, 0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
detailsFramework:SetFontColor(iconFrame.CountdownText, self.options.text_color)
|
||||
|
||||
self.NextIcon = self.NextIcon + 1
|
||||
return iconFrame
|
||||
end,
|
||||
|
||||
--adds only if not existing already in the cache
|
||||
AddSpecificIcon = function(self, identifierKey, spellId, borderColor, startTime, duration, forceTexture, descText, count, debuffType, caster, canStealOrPurge, spellName, isBuff)
|
||||
if (not identifierKey or identifierKey == "") then
|
||||
return
|
||||
end
|
||||
|
||||
if (not self.AuraCache[identifierKey]) then
|
||||
local icon = self:SetIcon(spellId, borderColor, startTime, duration, forceTexture, descText, count, debuffType, caster, canStealOrPurge, spellName, isBuff or false)
|
||||
icon.identifierKey = identifierKey
|
||||
self.AuraCache[identifierKey] = true
|
||||
end
|
||||
end,
|
||||
|
||||
SetIcon = function(self, spellId, borderColor, startTime, duration, forceTexture, descText, count, debuffType, caster, canStealOrPurge, spellName, isBuff, modRate)
|
||||
local actualSpellName, _, spellIcon = GetSpellInfo(spellId)
|
||||
|
||||
if forceTexture then
|
||||
spellIcon = forceTexture
|
||||
end
|
||||
|
||||
spellName = spellName or actualSpellName or "unknown_aura"
|
||||
modRate = modRate or 1
|
||||
|
||||
if (spellIcon) then
|
||||
local iconFrame = self:GetIcon()
|
||||
iconFrame.Texture:SetTexture(spellIcon)
|
||||
iconFrame.Texture:SetTexCoord(unpack(self.options.texcoord))
|
||||
|
||||
if (borderColor) then
|
||||
iconFrame:SetBackdropBorderColor(detailsFramework:ParseColors(borderColor))
|
||||
else
|
||||
iconFrame:SetBackdropBorderColor(0, 0, 0 ,0)
|
||||
end
|
||||
|
||||
if (startTime) then
|
||||
CooldownFrame_Set(iconFrame.Cooldown, startTime, duration, true, true, modRate)
|
||||
|
||||
if (self.options.show_text) then
|
||||
iconFrame.CountdownText:Show()
|
||||
|
||||
local now = GetTime()
|
||||
|
||||
iconFrame.timeRemaining = (startTime + duration - now) / modRate
|
||||
iconFrame.expirationTime = startTime + duration
|
||||
|
||||
local formattedTime = (iconFrame.timeRemaining > 0) and self.options.decimal_timer and iconFrame.parentIconRow.FormatCooldownTimeDecimal(iconFrame.timeRemaining) or iconFrame.parentIconRow.FormatCooldownTime(iconFrame.timeRemaining) or ""
|
||||
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:SetFontFace (iconFrame.CountdownText, self.options.text_font)
|
||||
detailsFramework:SetFontOutline (iconFrame.CountdownText, self.options.text_outline)
|
||||
|
||||
if self.options.on_tick_cooldown_update then
|
||||
iconFrame.lastUpdateCooldown = now
|
||||
iconFrame:SetScript("OnUpdate", self.OnIconTick)
|
||||
else
|
||||
iconFrame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
else
|
||||
iconFrame:SetScript("OnUpdate", nil)
|
||||
iconFrame.CountdownText:Hide()
|
||||
end
|
||||
|
||||
iconFrame.Cooldown:SetReverse(self.options.cooldown_reverse)
|
||||
iconFrame.Cooldown:SetDrawSwipe(self.options.cooldown_swipe_enabled)
|
||||
iconFrame.Cooldown:SetEdgeTexture(self.options.cooldown_edge_texture)
|
||||
iconFrame.Cooldown:SetHideCountdownNumbers(self.options.surpress_blizzard_cd_timer)
|
||||
else
|
||||
iconFrame.timeRemaining = nil
|
||||
iconFrame.expirationTime = nil
|
||||
iconFrame:SetScript("OnUpdate", nil)
|
||||
iconFrame.CountdownText:Hide()
|
||||
end
|
||||
|
||||
if (descText and self.options.desc_text) then
|
||||
iconFrame.Desc:Show()
|
||||
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:SetFontFace(iconFrame.Desc, self.options.desc_text_font)
|
||||
detailsFramework:SetFontOutline(iconFrame.Desc, self.options.desc_text_outline)
|
||||
else
|
||||
iconFrame.Desc:Hide()
|
||||
end
|
||||
|
||||
if (count and count > 1 and self.options.stack_text) then
|
||||
iconFrame.StackText:Show()
|
||||
iconFrame.StackText:SetText(count)
|
||||
iconFrame.StackText:SetTextColor(detailsFramework:ParseColors(self.options.stack_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:SetFontFace(iconFrame.StackText, self.options.stack_text_font)
|
||||
detailsFramework:SetFontOutline(iconFrame.StackText, self.options.stack_text_outline)
|
||||
else
|
||||
iconFrame.StackText:Hide()
|
||||
end
|
||||
|
||||
PixelUtil.SetSize(iconFrame, self.options.icon_width, self.options.icon_height)
|
||||
iconFrame:Show()
|
||||
|
||||
--update the size of the frame
|
||||
self:SetWidth((self.options.left_padding * 2) + (self.options.icon_padding * (self.NextIcon-2)) + (self.options.icon_width * (self.NextIcon - 1)))
|
||||
self:SetHeight(self.options.icon_height + (self.options.top_padding * 2))
|
||||
|
||||
--make information available
|
||||
iconFrame.spellId = spellId
|
||||
iconFrame.startTime = startTime
|
||||
iconFrame.duration = duration
|
||||
iconFrame.count = count
|
||||
iconFrame.debuffType = debuffType
|
||||
iconFrame.caster = caster
|
||||
iconFrame.canStealOrPurge = canStealOrPurge
|
||||
iconFrame.isBuff = isBuff
|
||||
iconFrame.spellName = spellName
|
||||
|
||||
iconFrame.identifierKey = nil -- only used for "specific" add/remove
|
||||
|
||||
--add the spell into the cache
|
||||
self.AuraCache[spellId or -1] = true
|
||||
self.AuraCache[spellName] = true
|
||||
self.AuraCache.canStealOrPurge = self.AuraCache.canStealOrPurge or canStealOrPurge
|
||||
self.AuraCache.hasEnrage = self.AuraCache.hasEnrage or debuffType == "" --yes, enrages are empty-string...
|
||||
|
||||
--show the frame
|
||||
self:Show()
|
||||
|
||||
return iconFrame
|
||||
end
|
||||
end,
|
||||
|
||||
OnIconTick = function(self, deltaTime)
|
||||
local now = GetTime()
|
||||
if (self.lastUpdateCooldown + 0.05) <= now then
|
||||
self.timeRemaining = self.expirationTime - now
|
||||
if self.timeRemaining > 0 then
|
||||
if self.parentIconRow.options.decimal_timer then
|
||||
self.CountdownText:SetText(self.parentIconRow.FormatCooldownTimeDecimal(self.timeRemaining))
|
||||
else
|
||||
self.CountdownText:SetText(self.parentIconRow.FormatCooldownTime(self.timeRemaining))
|
||||
end
|
||||
else
|
||||
self.CountdownText:SetText("")
|
||||
end
|
||||
self.lastUpdateCooldown = now
|
||||
end
|
||||
end,
|
||||
|
||||
FormatCooldownTime = function(formattedTime)
|
||||
if (formattedTime >= 3600) then
|
||||
formattedTime = math.floor(formattedTime / 3600) .. "h"
|
||||
|
||||
elseif (formattedTime >= 60) then
|
||||
formattedTime = math.floor(formattedTime / 60) .. "m"
|
||||
|
||||
else
|
||||
formattedTime = math.floor(formattedTime)
|
||||
end
|
||||
return formattedTime
|
||||
end,
|
||||
|
||||
FormatCooldownTimeDecimal = function(formattedTime)
|
||||
if formattedTime < 10 then
|
||||
return ("%.1f"):format(formattedTime)
|
||||
|
||||
elseif formattedTime < 60 then
|
||||
return ("%d"):format(formattedTime)
|
||||
|
||||
elseif formattedTime < 3600 then
|
||||
return ("%d:%02d"):format(formattedTime/60%60, formattedTime%60)
|
||||
|
||||
elseif formattedTime < 86400 then
|
||||
return ("%dh %02dm"):format(formattedTime/(3600), formattedTime/60%60)
|
||||
|
||||
else
|
||||
return ("%dd %02dh"):format(formattedTime/86400, (formattedTime/3600) - (math.floor(formattedTime/86400) * 24))
|
||||
end
|
||||
end,
|
||||
|
||||
RemoveSpecificIcon = function(self, identifierKey)
|
||||
if (not identifierKey or identifierKey == "") then
|
||||
return
|
||||
end
|
||||
|
||||
table.wipe(self.AuraCache)
|
||||
|
||||
local iconPool = self.IconPool
|
||||
local countStillShown = 0
|
||||
|
||||
for i = 1, self.NextIcon -1 do
|
||||
local iconFrame = iconPool[i]
|
||||
if (iconFrame.identifierKey and iconFrame.identifierKey == identifierKey) then
|
||||
iconFrame:Hide()
|
||||
iconFrame:ClearAllPoints()
|
||||
iconFrame.identifierKey = nil
|
||||
else
|
||||
self.AuraCache[iconFrame.spellId] = true
|
||||
self.AuraCache[iconFrame.spellName] = true
|
||||
self.AuraCache.canStealOrPurge = self.AuraCache.canStealOrPurge or iconFrame.canStealOrPurge
|
||||
self.AuraCache.hasEnrage = self.AuraCache.hasEnrage or iconFrame.debuffType == "" --yes, enrages are empty-string...
|
||||
countStillShown = countStillShown + 1
|
||||
end
|
||||
end
|
||||
|
||||
self:AlignAuraIcons()
|
||||
end,
|
||||
|
||||
ClearIcons = function(self, resetBuffs, resetDebuffs)
|
||||
resetBuffs = resetBuffs ~= false
|
||||
resetDebuffs = resetDebuffs ~= false
|
||||
table.wipe(self.AuraCache)
|
||||
|
||||
local iconPool = self.IconPool
|
||||
|
||||
for i = 1, self.NextIcon -1 do
|
||||
local iconFrame = iconPool[i]
|
||||
if (iconFrame.isBuff == nil) then
|
||||
iconFrame:Hide()
|
||||
iconFrame:ClearAllPoints()
|
||||
|
||||
elseif (resetBuffs and iconFrame.isBuff) then
|
||||
iconFrame:Hide()
|
||||
iconFrame:ClearAllPoints()
|
||||
|
||||
elseif (resetDebuffs and not iconFrame.isBuff) then
|
||||
iconFrame:Hide()
|
||||
iconFrame:ClearAllPoints()
|
||||
|
||||
else
|
||||
self.AuraCache[iconFrame.spellId] = true
|
||||
self.AuraCache[iconFrame.spellName] = true
|
||||
self.AuraCache.canStealOrPurge = self.AuraCache.canStealOrPurge or iconFrame.canStealOrPurge
|
||||
self.AuraCache.hasEnrage = self.AuraCache.hasEnrage or iconFrame.debuffType == "" --yes, enrages are empty-string...
|
||||
end
|
||||
end
|
||||
|
||||
self:AlignAuraIcons()
|
||||
end,
|
||||
|
||||
AlignAuraIcons = function(self)
|
||||
local iconPool = self.IconPool
|
||||
local iconAmount = #iconPool
|
||||
local countStillShown = 0
|
||||
|
||||
table.sort(iconPool, function(i1, i2) return i1:IsShown() and not i2:IsShown() end)
|
||||
|
||||
if iconAmount == 0 then
|
||||
self:Hide()
|
||||
else
|
||||
--re-anchor not hidden
|
||||
for i = 1, iconAmount do
|
||||
local iconFrame = iconPool[i]
|
||||
local anchor = self.options.anchor
|
||||
local anchorTo = i == 1 and self or self.IconPool[i - 1]
|
||||
local xPadding = i == 1 and self.options.left_padding or self.options.icon_padding or 1
|
||||
local growDirection = self.options.grow_direction
|
||||
|
||||
countStillShown = countStillShown + (iconFrame:IsShown() and 1 or 0)
|
||||
|
||||
iconFrame:ClearAllPoints()
|
||||
if (growDirection == 1) then --grow to right
|
||||
if (i == 1) then
|
||||
PixelUtil.SetPoint(iconFrame, "left", anchorTo, "left", xPadding, 0)
|
||||
else
|
||||
PixelUtil.SetPoint(iconFrame, "left", anchorTo, "right", xPadding, 0)
|
||||
end
|
||||
elseif (growDirection == 2) then --grow to left
|
||||
if (i == 1) then
|
||||
PixelUtil.SetPoint(iconFrame, "right", anchorTo, "right", xPadding, 0)
|
||||
else
|
||||
PixelUtil.SetPoint(iconFrame, "right", anchorTo, "left", xPadding, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.NextIcon = countStillShown + 1
|
||||
end,
|
||||
|
||||
GetIconGrowDirection = function(self)
|
||||
local side = self.options.anchor.side
|
||||
|
||||
if (side == 1) then
|
||||
return 1
|
||||
elseif (side == 2) then
|
||||
return 2
|
||||
elseif (side == 3) then
|
||||
return 1
|
||||
elseif (side == 4) then
|
||||
return 1
|
||||
elseif (side == 5) then
|
||||
return 2
|
||||
elseif (side == 6) then
|
||||
return 1
|
||||
elseif (side == 7) then
|
||||
return 2
|
||||
elseif (side == 8) then
|
||||
return 1
|
||||
elseif (side == 9) then
|
||||
return 1
|
||||
elseif (side == 10) then
|
||||
return 1
|
||||
elseif (side == 11) then
|
||||
return 2
|
||||
elseif (side == 12) then
|
||||
return 1
|
||||
elseif (side == 13) then
|
||||
return 1
|
||||
end
|
||||
end,
|
||||
|
||||
OnOptionChanged = function(self, optionName)
|
||||
self:SetBackdropColor(unpack(self.options.backdrop_color))
|
||||
self:SetBackdropBorderColor(unpack(self.options.backdrop_border_color))
|
||||
end,
|
||||
}
|
||||
|
||||
local default_icon_row_options = {
|
||||
icon_width = 20,
|
||||
icon_height = 20,
|
||||
texcoord = {.1, .9, .1, .9},
|
||||
show_text = true,
|
||||
text_color = {1, 1, 1, 1},
|
||||
text_size = 12,
|
||||
text_font = "Arial Narrow",
|
||||
text_outline = "NONE",
|
||||
text_anchor = "center",
|
||||
text_rel_anchor = "center",
|
||||
text_x_offset = 0,
|
||||
text_y_offset = 0,
|
||||
desc_text = true,
|
||||
desc_text_color = {1, 1, 1, 1},
|
||||
desc_text_size = 7,
|
||||
desc_text_font = "Arial Narrow",
|
||||
desc_text_outline = "NONE",
|
||||
desc_text_anchor = "bottom",
|
||||
desc_text_rel_anchor = "top",
|
||||
desc_text_x_offset = 0,
|
||||
desc_text_y_offset = 2,
|
||||
stack_text = true,
|
||||
stack_text_color = {1, 1, 1, 1},
|
||||
stack_text_size = 10,
|
||||
stack_text_font = "Arial Narrow",
|
||||
stack_text_outline = "NONE",
|
||||
stack_text_anchor = "center",
|
||||
stack_text_rel_anchor = "bottomright",
|
||||
stack_text_x_offset = 0,
|
||||
stack_text_y_offset = 0,
|
||||
left_padding = 1, --distance between right and left
|
||||
top_padding = 1, --distance between top and bottom
|
||||
icon_padding = 1, --distance between each icon
|
||||
backdrop = {},
|
||||
backdrop_color = {0, 0, 0, 0.5},
|
||||
backdrop_border_color = {0, 0, 0, 1},
|
||||
anchor = {side = 6, x = 2, y = 0},
|
||||
grow_direction = 1, --1 = to right 2 = to left
|
||||
surpress_blizzard_cd_timer = false,
|
||||
surpress_tulla_omni_cc = false,
|
||||
on_tick_cooldown_update = true,
|
||||
decimal_timer = false,
|
||||
cooldown_reverse = false,
|
||||
cooldown_swipe_enabled = true,
|
||||
cooldown_edge_texture = "Interface\\Cooldown\\edge",
|
||||
}
|
||||
|
||||
function detailsFramework:CreateIconRow(parent, name, options)
|
||||
local newIconRowFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
newIconRowFrame.IconPool = {}
|
||||
newIconRowFrame.NextIcon = 1
|
||||
newIconRowFrame.AuraCache = {}
|
||||
|
||||
detailsFramework:Mixin(newIconRowFrame, detailsFramework.IconMixin)
|
||||
detailsFramework:Mixin(newIconRowFrame, detailsFramework.OptionsFunctions)
|
||||
|
||||
newIconRowFrame:BuildOptionsTable(default_icon_row_options, options)
|
||||
|
||||
newIconRowFrame:SetSize(newIconRowFrame.options.icon_width, newIconRowFrame.options.icon_height + (newIconRowFrame.options.top_padding * 2))
|
||||
|
||||
newIconRowFrame:SetBackdrop(newIconRowFrame.options.backdrop)
|
||||
newIconRowFrame:SetBackdropColor(unpack(newIconRowFrame.options.backdrop_color))
|
||||
newIconRowFrame:SetBackdropBorderColor(unpack(newIconRowFrame.options.backdrop_border_color))
|
||||
|
||||
return newIconRowFrame
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
local detailsFramework = _G["DetailsFramework"]
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
--namespace
|
||||
detailsFramework.Items = {}
|
||||
|
||||
local containerAPIVersion = 1
|
||||
if (detailsFramework.IsDragonflightAndBeyond()) then
|
||||
containerAPIVersion = 2
|
||||
end
|
||||
|
||||
function detailsFramework.Items.GetContainerItemInfo(containerIndex, slotIndex)
|
||||
if (containerAPIVersion == 2 and C_Container and C_Container.GetContainerItemInfo) then
|
||||
local itemInfo = C_Container.GetContainerItemInfo(containerIndex, slotIndex)
|
||||
return itemInfo.iconFileID, itemInfo.stackCount, itemInfo.isLocked, itemInfo.quality, itemInfo.isReadable, itemInfo.hasLoot, itemInfo.hyperlink, itemInfo.isFiltered, itemInfo.hasNoValue, itemInfo.itemID, itemInfo.isBound
|
||||
else
|
||||
return GetContainerItemInfo(containerIndex, slotIndex)
|
||||
end
|
||||
end
|
||||
|
||||
function detailsFramework.Items.IsItemSoulbound(containerIndex, slotIndex)
|
||||
local bIsBound = select(11, detailsFramework.Items.GetContainerItemInfo(containerIndex, slotIndex))
|
||||
return bIsBound
|
||||
end
|
||||
@@ -1,382 +0,0 @@
|
||||
|
||||
local detailsFramework = _G["DetailsFramework"]
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local loadedAPILabelFunctions = false
|
||||
|
||||
do
|
||||
local metaPrototype = {
|
||||
WidgetType = "label",
|
||||
dversion = detailsFramework.dversion,
|
||||
}
|
||||
|
||||
--check if there's a metaPrototype already existing
|
||||
if (_G[detailsFramework.GlobalWidgetControlNames["label"]]) then
|
||||
--get the already existing metaPrototype
|
||||
local oldMetaPrototype = _G[detailsFramework.GlobalWidgetControlNames ["label"]]
|
||||
--check if is older
|
||||
if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < detailsFramework.dversion) ) then
|
||||
--the version is older them the currently loading one
|
||||
--copy the new values into the old metatable
|
||||
for funcName, _ in pairs(metaPrototype) do
|
||||
oldMetaPrototype[funcName] = metaPrototype[funcName]
|
||||
end
|
||||
end
|
||||
else
|
||||
--first time loading the framework
|
||||
_G[detailsFramework.GlobalWidgetControlNames ["label"]] = metaPrototype
|
||||
end
|
||||
end
|
||||
|
||||
local LabelMetaFunctions = _G[detailsFramework.GlobalWidgetControlNames ["label"]]
|
||||
|
||||
detailsFramework:Mixin(LabelMetaFunctions, detailsFramework.SetPointMixin)
|
||||
detailsFramework:Mixin(LabelMetaFunctions, detailsFramework.ScriptHookMixin)
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--metatables
|
||||
|
||||
LabelMetaFunctions.__call = function(object, value)
|
||||
return object.label:SetText(value)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--members
|
||||
|
||||
--get text
|
||||
local gmember_text = function(object)
|
||||
return object.label:GetText()
|
||||
end
|
||||
|
||||
--text width
|
||||
local gmember_width = function(object)
|
||||
return object.label:GetStringWidth()
|
||||
end
|
||||
|
||||
--text height
|
||||
local gmember_height = function(object)
|
||||
return object.label:GetStringHeight()
|
||||
end
|
||||
|
||||
--text color
|
||||
local gmember_textcolor = function(object)
|
||||
return object.label:GetTextColor()
|
||||
end
|
||||
|
||||
--text font
|
||||
local gmember_textfont = function(object)
|
||||
local fontface = object.label:GetFont()
|
||||
return fontface
|
||||
end
|
||||
|
||||
--text size
|
||||
local gmember_textsize = function(object)
|
||||
local _, fontsize = object.label:GetFont()
|
||||
return fontsize
|
||||
end
|
||||
|
||||
LabelMetaFunctions.GetMembers = LabelMetaFunctions.GetMembers or {}
|
||||
detailsFramework:Mixin(LabelMetaFunctions.GetMembers, detailsFramework.LayeredRegionMetaFunctionsGet)
|
||||
detailsFramework:Mixin(LabelMetaFunctions.GetMembers, detailsFramework.DefaultMetaFunctionsGet)
|
||||
|
||||
LabelMetaFunctions.GetMembers["width"] = gmember_width
|
||||
LabelMetaFunctions.GetMembers["height"] = gmember_height
|
||||
LabelMetaFunctions.GetMembers["text"] = gmember_text
|
||||
LabelMetaFunctions.GetMembers["fontcolor"] = gmember_textcolor
|
||||
LabelMetaFunctions.GetMembers["fontface"] = gmember_textfont
|
||||
LabelMetaFunctions.GetMembers["fontsize"] = gmember_textsize
|
||||
LabelMetaFunctions.GetMembers["textcolor"] = gmember_textcolor --alias
|
||||
LabelMetaFunctions.GetMembers["textfont"] = gmember_textfont --alias
|
||||
LabelMetaFunctions.GetMembers["textsize"] = gmember_textsize --alias
|
||||
|
||||
LabelMetaFunctions.__index = function(object, key)
|
||||
local func = LabelMetaFunctions.GetMembers[key]
|
||||
if (func) then
|
||||
return func(object, key)
|
||||
end
|
||||
|
||||
local alreadyHaveKey = rawget(object, key)
|
||||
if (alreadyHaveKey) then
|
||||
return alreadyHaveKey
|
||||
end
|
||||
|
||||
return LabelMetaFunctions[key]
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--text
|
||||
local smember_text = function(object, value)
|
||||
return object.label:SetText(value)
|
||||
end
|
||||
|
||||
--text color
|
||||
local smember_textcolor = function(object, value)
|
||||
local value1, value2, value3, value4 = detailsFramework:ParseColors(value)
|
||||
return object.label:SetTextColor(value1, value2, value3, value4)
|
||||
end
|
||||
|
||||
--text font
|
||||
local smember_textfont = function(object, value)
|
||||
return detailsFramework:SetFontFace(object.label, value)
|
||||
end
|
||||
|
||||
--text size
|
||||
local smember_textsize = function(object, value)
|
||||
return detailsFramework:SetFontSize(object.label, value)
|
||||
end
|
||||
|
||||
--text align
|
||||
local smember_textalign = function(object, value)
|
||||
if (value == "<") then
|
||||
value = "left"
|
||||
elseif (value == ">") then
|
||||
value = "right"
|
||||
elseif (value == "|") then
|
||||
value = "center"
|
||||
end
|
||||
return object.label:SetJustifyH(value)
|
||||
end
|
||||
|
||||
--text valign
|
||||
local smember_textvalign = function(object, value)
|
||||
if (value == "^") then
|
||||
value = "top"
|
||||
elseif (value == "_") then
|
||||
value = "bottom"
|
||||
elseif (value == "|") then
|
||||
value = "middle"
|
||||
end
|
||||
return object.label:SetJustifyV(value)
|
||||
end
|
||||
|
||||
--field size width
|
||||
local smember_width = function(object, value)
|
||||
return object.label:SetWidth(value)
|
||||
end
|
||||
|
||||
--field size height
|
||||
local smember_height = function(object, value)
|
||||
return object.label:SetHeight(value)
|
||||
end
|
||||
|
||||
--outline (shadow)
|
||||
local smember_outline = function(object, value)
|
||||
detailsFramework:SetFontOutline(object.label, value)
|
||||
end
|
||||
|
||||
--text rotation
|
||||
local smember_rotation = function(object, rotation)
|
||||
if (type(rotation) == "number") then
|
||||
if (not object.__rotationAnimation) then
|
||||
object.__rotationAnimation = detailsFramework:CreateAnimationHub(object.label)
|
||||
object.__rotationAnimation.rotator = detailsFramework:CreateAnimation(object.__rotationAnimation, "rotation", 1, 0, 0)
|
||||
object.__rotationAnimation.rotator:SetEndDelay(10^8)
|
||||
object.__rotationAnimation.rotator:SetSmoothProgress(1)
|
||||
end
|
||||
object.__rotationAnimation.rotator:SetDegrees(rotation)
|
||||
object.__rotationAnimation:Play()
|
||||
object.__rotationAnimation:Pause()
|
||||
end
|
||||
end
|
||||
|
||||
LabelMetaFunctions.SetMembers = LabelMetaFunctions.SetMembers or {}
|
||||
detailsFramework:Mixin(LabelMetaFunctions.SetMembers, detailsFramework.LayeredRegionMetaFunctionsSet)
|
||||
detailsFramework:Mixin(LabelMetaFunctions.SetMembers, detailsFramework.DefaultMetaFunctionsSet)
|
||||
|
||||
LabelMetaFunctions.SetMembers["align"] = smember_textalign
|
||||
LabelMetaFunctions.SetMembers["valign"] = smember_textvalign
|
||||
LabelMetaFunctions.SetMembers["text"] = smember_text
|
||||
LabelMetaFunctions.SetMembers["width"] = smember_width
|
||||
LabelMetaFunctions.SetMembers["height"] = smember_height
|
||||
LabelMetaFunctions.SetMembers["fontcolor"] = smember_textcolor
|
||||
LabelMetaFunctions.SetMembers["color"] = smember_textcolor--alias
|
||||
LabelMetaFunctions.SetMembers["fontface"] = smember_textfont
|
||||
LabelMetaFunctions.SetMembers["fontsize"] = smember_textsize
|
||||
LabelMetaFunctions.SetMembers["textcolor"] = smember_textcolor--alias
|
||||
LabelMetaFunctions.SetMembers["textfont"] = smember_textfont--alias
|
||||
LabelMetaFunctions.SetMembers["textsize"] = smember_textsize--alias
|
||||
LabelMetaFunctions.SetMembers["shadow"] = smember_outline
|
||||
LabelMetaFunctions.SetMembers["outline"] = smember_outline--alias
|
||||
LabelMetaFunctions.SetMembers["rotation"] = smember_rotation
|
||||
|
||||
LabelMetaFunctions.__newindex = function(object, key, value)
|
||||
local func = LabelMetaFunctions.SetMembers[key]
|
||||
if (func) then
|
||||
return func(object, value)
|
||||
else
|
||||
return rawset(object, key, value)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--methods
|
||||
|
||||
---set the text of the label and truncate it is its width passes 'maxWidth' threshold
|
||||
---@param self df_label
|
||||
---@param text string
|
||||
---@param maxWidth width
|
||||
function LabelMetaFunctions:SetTextTruncated(text, maxWidth)
|
||||
self.widget:SetText(text)
|
||||
detailsFramework:TruncateText(self.widget, maxWidth)
|
||||
end
|
||||
|
||||
---set the text color
|
||||
---@param self df_label
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
function LabelMetaFunctions:SetTextColor(red, green, blue, alpha)
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
return self.label:SetTextColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--template
|
||||
|
||||
function LabelMetaFunctions:SetTemplate(template)
|
||||
if (template.size) then
|
||||
detailsFramework:SetFontSize(self.label, template.size)
|
||||
end
|
||||
if (template.color) then
|
||||
local r, g, b, a = detailsFramework:ParseColors(template.color)
|
||||
self:SetTextColor(r, g, b, a)
|
||||
end
|
||||
if (template.font) then
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local font = SharedMedia:Fetch("font", template.font)
|
||||
detailsFramework:SetFontFace(self.label, font)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--object constructor
|
||||
|
||||
---@class df_label
|
||||
---@field widget fontstring widget and label points to the same fontstring
|
||||
---@field label fontstring widget and label points to the same fontstring
|
||||
---@field align justifyh
|
||||
---@field valign justifyv
|
||||
---@field text string
|
||||
---@field width width
|
||||
---@field height height
|
||||
---@field fontcolor any
|
||||
---@field color any
|
||||
---@field fontface string
|
||||
---@field fontsize number
|
||||
---@field textcolor any
|
||||
---@field textfont string
|
||||
---@field textsize number
|
||||
---@field shadow fontflags
|
||||
---@field outline fontflags
|
||||
---@field rotation number
|
||||
---@field SetTemplate fun(self: df_label, template: table) set the fontstring visual by a template
|
||||
---@field SetTextColor fun(self: df_label, red: any, green: number|nil, blue: number|nil, alpha: number|nil) set the button text color
|
||||
---@field SetTextTruncated fun(self: df_label, text: string, maxWidth: width)
|
||||
|
||||
---create a new label object
|
||||
---@param parent frame
|
||||
---@param text string
|
||||
---@param size number|nil
|
||||
---@param color any|nil
|
||||
---@param font string|nil
|
||||
---@param member string|nil
|
||||
---@param name string|nil
|
||||
---@param layer drawlayer|nil
|
||||
---@return df_label|nil
|
||||
function detailsFramework:CreateLabel(parent, text, size, color, font, member, name, layer)
|
||||
return detailsFramework:NewLabel(parent, nil, name, member, text, font, size, color, layer)
|
||||
end
|
||||
|
||||
function detailsFramework:NewLabel(parent, container, name, member, text, font, size, color, layer)
|
||||
if (not parent) then
|
||||
return error("Details! Framework: parent not found.", 2)
|
||||
end
|
||||
if (not container) then
|
||||
container = parent
|
||||
end
|
||||
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkLabelNumber" .. detailsFramework.LabelNameCounter
|
||||
detailsFramework.LabelNameCounter = detailsFramework.LabelNameCounter + 1
|
||||
end
|
||||
|
||||
if (name:find("$parent")) then
|
||||
local parentName = detailsFramework.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
|
||||
---@type df_label
|
||||
local labelObject = {type = "label", dframework = true}
|
||||
|
||||
if (member) then
|
||||
parent[member] = labelObject
|
||||
end
|
||||
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
|
||||
if (container.dframework) then
|
||||
container = container.widget
|
||||
end
|
||||
|
||||
if (not font or font == "") then
|
||||
font = "GameFontNormal"
|
||||
end
|
||||
|
||||
labelObject.label = parent:CreateFontString(name, layer or "OVERLAY", font)
|
||||
labelObject.widget = labelObject.label
|
||||
labelObject.label.MyObject = labelObject
|
||||
|
||||
if (not loadedAPILabelFunctions) then
|
||||
loadedAPILabelFunctions = true
|
||||
local idx = getmetatable(labelObject.label).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not LabelMetaFunctions[funcName]) then
|
||||
LabelMetaFunctions[funcName] = function(object, ...)
|
||||
local x = loadstring( "return _G['"..object.label:GetName().."']:"..funcName.."(...)")
|
||||
return x(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--if the text is a table, it means a language table has been passed
|
||||
if (type(text) == "table") then
|
||||
local locTable = text
|
||||
if (detailsFramework.Language.IsLocTable(locTable)) then
|
||||
detailsFramework.Language.SetTextWithLocTable(labelObject.widget, locTable)
|
||||
else
|
||||
labelObject.label:SetText(text)
|
||||
end
|
||||
else
|
||||
labelObject.label:SetText(text)
|
||||
end
|
||||
|
||||
labelObject.label:SetJustifyH("left")
|
||||
|
||||
if (color) then
|
||||
local r, g, b, a = detailsFramework:ParseColors(color)
|
||||
labelObject.label:SetTextColor(r, g, b, a)
|
||||
end
|
||||
|
||||
if (size and type(size) == "number") then
|
||||
detailsFramework:SetFontSize(labelObject.label, size)
|
||||
end
|
||||
|
||||
labelObject.HookList = {}
|
||||
|
||||
setmetatable(labelObject, LabelMetaFunctions)
|
||||
|
||||
--if template has been passed as the third parameter
|
||||
if (size and type(size) == "table") then
|
||||
labelObject:SetTemplate(size)
|
||||
end
|
||||
|
||||
return labelObject
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,41 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
|
||||
|
||||
<Script file ="DFPixelUtil.lua"/>
|
||||
<Script file="fw.lua"/>
|
||||
<Script file="mixins.lua"/>
|
||||
<Script file="util.lua"/>
|
||||
<Script file="header.lua"/>
|
||||
<Script file="containers.lua"/>
|
||||
<Script file="iteminfo.lua"/>
|
||||
<Script file="addon.lua"/>
|
||||
<Script file="colors.lua"/>
|
||||
<Script file="help.lua"/>
|
||||
<Script file="schedules.lua"/>
|
||||
<Script file="label.lua"/>
|
||||
<Script file="picture.lua"/>
|
||||
<Script file="slider.lua"/>
|
||||
<Script file="scrollbar.lua"/>
|
||||
<Script file="spells.lua"/>
|
||||
<Script file="math.lua"/>
|
||||
<Script file="savedvars.lua"/>
|
||||
<Script file="languages.lua"/>
|
||||
<Script file="timebar.lua"/>
|
||||
<Script file="charts.lua"/>
|
||||
<Script file="scripting.lua"/>
|
||||
<Script file="externals.lua"/>
|
||||
<Script file="frames.lua"/>
|
||||
|
||||
<Include file="tutorial_alert.xml"/>
|
||||
<Include file="split_bar.xml"/>
|
||||
<Include file="textentry.xml"/>
|
||||
<Include file="button.xml"/>
|
||||
<Include file="cooltip.xml"/>
|
||||
<Include file="dropdown.xml"/>
|
||||
<Include file="normal_bar.xml"/>
|
||||
<Include file="panel.xml"/>
|
||||
|
||||
<Script file="icon.lua"/>
|
||||
<Script file="pictureedit.lua"/>
|
||||
<Script file="auras.lua"/>
|
||||
<Script file="tabcontainer.lua"/>
|
||||
</Ui>
|
||||
@@ -1,176 +0,0 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local UnitExists = UnitExists
|
||||
local atan2 = math.atan2
|
||||
local pi = math.pi
|
||||
local abs = math.abs
|
||||
|
||||
SMALL_FLOAT = 0.000001
|
||||
|
||||
--find distance between two players
|
||||
function DF:GetDistance_Unit(unit1, unit2)
|
||||
if (UnitExists(unit1) and UnitExists(unit2)) then
|
||||
local u1X, u1Y = UnitPosition(unit1)
|
||||
local u2X, u2Y = UnitPosition(unit2)
|
||||
|
||||
local dX = u2X - u1X
|
||||
local dY = u2Y - u1Y
|
||||
|
||||
return ((dX*dX) + (dY*dY)) ^ .5
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
--find distance between two points
|
||||
function DF:GetDistance_Point(x1, y1, x2, y2)
|
||||
local dx = x2 - x1
|
||||
local dy = y2 - y1
|
||||
return ((dx * dx) + (dy * dy)) ^ .5
|
||||
end
|
||||
|
||||
--find a rotation for an object from a point to another point
|
||||
function DF:FindLookAtRotation(x1, y1, x2, y2)
|
||||
return atan2 (y2 - y1, x2 - x1) + pi
|
||||
end
|
||||
|
||||
--find the value scale between two given values. e.g: value of 500 in a range 0-100 result in 10 in a scale for 0-10
|
||||
function DF:MapRangeClamped(inputX, inputY, outputX, outputY, value)
|
||||
return DF:GetRangeValue(outputX, outputY, Clamp(DF:GetRangePercent(inputX, inputY, value), 0, 1))
|
||||
end
|
||||
|
||||
--find the value scale between two given values. e.g: value of 75 in a range 0-100 result in 7.5 in a scale for 0-10
|
||||
function DF:MapRangeUnclamped(inputX, inputY, outputX, outputY, value)
|
||||
return DF:GetRangeValue(outputX, outputY, DF:GetRangePercent(inputX, inputY, value))
|
||||
end
|
||||
|
||||
--find the normalized percent of the value in the range. e.g range of 200-400 and a value of 250 result in 0.25
|
||||
function DF:GetRangePercent(minValue, maxValue, value)
|
||||
return (value - minValue) / max((maxValue - minValue), SMALL_FLOAT)
|
||||
end
|
||||
|
||||
--find the value in the range given from a normalized percent. e.g range of 200-400 and a percent of 0.8 result in 360
|
||||
function DF:GetRangeValue(minValue, maxValue, percent)
|
||||
return Lerp(minValue, maxValue, percent)
|
||||
end
|
||||
|
||||
function DF:GetColorRangeValue(r1, g1, b1, r2, g2, b2, value)
|
||||
local newR = DF:LerpNorm(r1, r2, value)
|
||||
local newG = DF:LerpNorm(g1, g2, value)
|
||||
local newB = DF:LerpNorm(b1, b2, value)
|
||||
return newR, newG, newB
|
||||
end
|
||||
|
||||
--dot product of two 2D Vectors
|
||||
function DF:GetDotProduct(value1, value2)
|
||||
return (value1.x * value2.x) + (value1.y * value2.y)
|
||||
end
|
||||
|
||||
function DF:GetBezierPoint(value, point1, point2, point3)
|
||||
local bP1 = Lerp(point1, point2, value)
|
||||
local bP2 = Lerp(point2, point3, value)
|
||||
return Lerp(bP1, bP2, value)
|
||||
end
|
||||
|
||||
--normalized value 0-1 result in the value on the range given, e.g 200-400 range with a value of .5 result in 300
|
||||
function DF:LerpNorm(minValue, maxValue, value)
|
||||
return (minValue + value * (maxValue - minValue))
|
||||
end
|
||||
|
||||
--change the color by the deltaTime
|
||||
function DF:LerpLinearColor(deltaTime, interpSpeed, r1, g1, b1, r2, g2, b2)
|
||||
deltaTime = deltaTime * interpSpeed
|
||||
local r = r1 + (r2 - r1) * deltaTime
|
||||
local g = g1 + (g2 - g1) * deltaTime
|
||||
local b = b1 + (b2 - b1) * deltaTime
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
--check if a number is near another number by a tolerance
|
||||
function DF:IsNearlyEqual(value1, value2, tolerance)
|
||||
tolerance = tolerance or SMALL_FLOAT
|
||||
return abs(value1 - value2) <= tolerance
|
||||
end
|
||||
|
||||
--check if a number is near zero
|
||||
function DF:IsNearlyZero(value, tolerance)
|
||||
tolerance = tolerance or SMALL_FLOAT
|
||||
return abs(value) <= tolerance
|
||||
end
|
||||
|
||||
--check if a number is within a two other numbers, if isInclusive is true, it'll include the max value
|
||||
function DF:IsWithin(minValue, maxValue, value, isInclusive)
|
||||
if (isInclusive) then
|
||||
return ((value >= minValue) and (value <= maxValue))
|
||||
else
|
||||
return ((value >= minValue) and (value < maxValue))
|
||||
end
|
||||
end
|
||||
|
||||
--dont allow a number ot be lower or bigger than a certain range
|
||||
function DF:Clamp(minValue, maxValue, value)
|
||||
return value < minValue and minValue or value < maxValue and value or maxValue
|
||||
end
|
||||
|
||||
--from http://lua-users.org/wiki/SimpleRound cut fractions on a float
|
||||
function DF:Round(num, numDecimalPlaces)
|
||||
local mult = 10^(numDecimalPlaces or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
local BoundingBox = {}
|
||||
BoundingBox.CoordinatesData = {
|
||||
["topleft"] = {["x"] = 'number', ["y"] = 'number'},
|
||||
["topright"] = {["x"] = 'number', ["y"] = 'number'},
|
||||
["bottomleft"] = {["x"] = 'number', ["y"] = 'number'},
|
||||
["bottomright"] = {["x"] = 'number', ["y"] = 'number'},
|
||||
["center"] = {["x"] = 'number', ["y"] = 'number'},
|
||||
["width"] = 'number',
|
||||
["height"] = 'number',
|
||||
}
|
||||
|
||||
---@class objectcoordinates
|
||||
---@field topleft {["x"]: number, ["y"]: number}
|
||||
---@field topright {["x"]: number, ["y"]: number}
|
||||
---@field bottomleft {["x"]: number, ["y"]: number}
|
||||
---@field bottomright {["x"]: number, ["y"]: number}
|
||||
---@field center {["x"]: number, ["y"]: number}
|
||||
---@field width number
|
||||
---@field height number
|
||||
---@field left number
|
||||
---@field right number
|
||||
---@field top number
|
||||
---@field bottom number
|
||||
|
||||
---return the coordinates of the four corners of an object
|
||||
---@param object uiobject
|
||||
---@return objectcoordinates
|
||||
function DF:GetObjectCoordinates(object)
|
||||
local centerX, centerY = object:GetCenter()
|
||||
local width = object:GetWidth()
|
||||
local height = object:GetHeight()
|
||||
|
||||
local halfWidth = width / 2
|
||||
local halfHeight = height / 2
|
||||
|
||||
return {
|
||||
["width"] = width,
|
||||
["height"] = height,
|
||||
["left"] = centerX - halfWidth,
|
||||
["right"] = centerX + halfWidth,
|
||||
["top"] = centerY + halfHeight,
|
||||
["bottom"] = centerY - halfHeight,
|
||||
["center"] = {x = centerX, y = centerY},
|
||||
["topleft"] = {x = centerX - halfWidth, y = centerY + halfHeight},
|
||||
["topright"] = {x = centerX + halfWidth, y = centerY + halfHeight},
|
||||
["bottomleft"] = {x = centerX - halfWidth, y = centerY - halfHeight},
|
||||
["bottomright"] = {x = centerX + halfWidth, y = centerY - halfHeight},
|
||||
}
|
||||
end
|
||||
|
||||
function DF:ScaleBack()
|
||||
|
||||
end
|
||||
@@ -1,977 +0,0 @@
|
||||
|
||||
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) then
|
||||
GameCooltip:Preset(2)
|
||||
GameCooltip:AddLine(tooltipText)
|
||||
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 DetailsFramework.ScriptHookMixin
|
||||
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,
|
||||
}
|
||||
|
||||
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.SortFunctions)
|
||||
---add methods to be used on scrollframes
|
||||
---@class df_scrollboxmixin
|
||||
detailsFramework.ScrollBoxFunctions = {
|
||||
---refresh the scrollbox by resetting all lines created with :CreateLine(), then calling the refresh_func which was set at :CreateScrollBox()
|
||||
---@param self table
|
||||
---@return table
|
||||
Refresh = function(self)
|
||||
--hide all frames and tag as not in use
|
||||
self._LinesInUse = 0
|
||||
for index, frame in ipairs(self.Frames) do
|
||||
if (not self.DontHideChildrenOnPreRefresh) then
|
||||
frame:Hide()
|
||||
end
|
||||
frame._InUse = nil
|
||||
end
|
||||
|
||||
local offset = 0
|
||||
if (self.IsFauxScroll) then
|
||||
self:UpdateFaux(#self.data, self.LineAmount, self.LineHeight)
|
||||
offset = self:GetOffsetFaux()
|
||||
end
|
||||
|
||||
--call the refresh function
|
||||
detailsFramework:CoreDispatch((self:GetName() or "ScrollBox") .. ":Refresh()", self.refresh_func, self, self.data, offset, self.LineAmount)
|
||||
|
||||
--hide all frames that are not in use
|
||||
for index, frame in ipairs(self.Frames) do
|
||||
if (not frame._InUse) then
|
||||
frame:Hide()
|
||||
else
|
||||
frame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
self:Show()
|
||||
|
||||
local frameName = self:GetName()
|
||||
if (frameName) then
|
||||
if (self.HideScrollBar) then
|
||||
local scrollBar = _G[frameName .. "ScrollBar"]
|
||||
if (scrollBar) then
|
||||
scrollBar:Hide()
|
||||
end
|
||||
else
|
||||
--[=[ --maybe in the future I visit this again
|
||||
local scrollBar = _G[frameName .. "ScrollBar"]
|
||||
local height = self:GetHeight()
|
||||
local totalLinesRequired = #self.data
|
||||
local linesShown = self._LinesInUse
|
||||
|
||||
local percent = linesShown / totalLinesRequired
|
||||
local thumbHeight = height * percent
|
||||
scrollBar.ThumbTexture:SetSize(12, thumbHeight)
|
||||
print("thumbHeight:", thumbHeight)
|
||||
--]=]
|
||||
end
|
||||
end
|
||||
return self.Frames
|
||||
end,
|
||||
|
||||
OnVerticalScroll = function(self, offset)
|
||||
self:OnVerticalScrollFaux(offset, self.LineHeight, self.Refresh)
|
||||
return true
|
||||
end,
|
||||
|
||||
---create a line within the scrollbox
|
||||
---@param self table is the scrollbox
|
||||
---@param func function|nil function to create the line object, this function will receive the line index as argument and return a table with the line object
|
||||
---@return table line object (table)
|
||||
CreateLine = function(self, func)
|
||||
if (not func) then
|
||||
func = self.CreateLineFunc
|
||||
end
|
||||
|
||||
local okay, newLine = pcall(func, self, #self.Frames+1)
|
||||
if (okay) then
|
||||
if (not newLine) then
|
||||
error("ScrollFrame:CreateLine() function did not returned a line, use: 'return line'")
|
||||
end
|
||||
tinsert(self.Frames, newLine)
|
||||
newLine.Index = #self.Frames
|
||||
return newLine
|
||||
else
|
||||
error("ScrollFrame:CreateLine() error on creating a line: " .. newLine)
|
||||
end
|
||||
end,
|
||||
|
||||
CreateLines = function(self, callback, lineAmount)
|
||||
for i = 1, lineAmount do
|
||||
self:CreateLine(callback)
|
||||
end
|
||||
end,
|
||||
|
||||
GetLine = function(self, lineIndex)
|
||||
local line = self.Frames[lineIndex]
|
||||
if (line) then
|
||||
line._InUse = true
|
||||
end
|
||||
|
||||
self._LinesInUse = self._LinesInUse + 1
|
||||
return line
|
||||
end,
|
||||
|
||||
SetData = function(self, data)
|
||||
self.data = data
|
||||
end,
|
||||
GetData = function(self)
|
||||
return self.data
|
||||
end,
|
||||
|
||||
GetFrames = function(self)
|
||||
return self.Frames
|
||||
end,
|
||||
GetLines = function(self) --alias of GetFrames
|
||||
return self.Frames
|
||||
end,
|
||||
|
||||
GetNumFramesCreated = function(self)
|
||||
return #self.Frames
|
||||
end,
|
||||
|
||||
GetNumFramesShown = function(self)
|
||||
return self.LineAmount
|
||||
end,
|
||||
|
||||
SetNumFramesShown = function(self, newAmount)
|
||||
--hide frames which won't be used
|
||||
if (newAmount < #self.Frames) then
|
||||
for i = newAmount+1, #self.Frames do
|
||||
self.Frames[i]:Hide()
|
||||
end
|
||||
end
|
||||
--set the new amount
|
||||
self.LineAmount = newAmount
|
||||
end,
|
||||
|
||||
SetFramesHeight = function(self, height)
|
||||
self.LineHeight = height
|
||||
self:OnSizeChanged()
|
||||
self:Refresh()
|
||||
end,
|
||||
|
||||
OnSizeChanged = function(self)
|
||||
if (self.ReajustNumFrames) then
|
||||
--how many lines the scroll can show
|
||||
local amountOfFramesToShow = floor(self:GetHeight() / self.LineHeight)
|
||||
|
||||
--how many lines the scroll already have
|
||||
local totalFramesCreated = self:GetNumFramesCreated()
|
||||
|
||||
--how many lines are current shown
|
||||
local totalFramesShown = self:GetNumFramesShown()
|
||||
|
||||
--the amount of frames increased
|
||||
if (amountOfFramesToShow > totalFramesShown) then
|
||||
for i = totalFramesShown+1, amountOfFramesToShow do
|
||||
--check if need to create a new line
|
||||
if (i > totalFramesCreated) then
|
||||
self:CreateLine(self.CreateLineFunc)
|
||||
end
|
||||
end
|
||||
|
||||
--the amount of frames decreased
|
||||
elseif (amountOfFramesToShow < totalFramesShown) then
|
||||
--hide all frames above the new amount to show
|
||||
for i = totalFramesCreated, amountOfFramesToShow, -1 do
|
||||
if (self.Frames[i]) then
|
||||
self.Frames[i]:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--set the new amount of frames
|
||||
self:SetNumFramesShown(amountOfFramesToShow)
|
||||
--refresh lines
|
||||
self:Refresh()
|
||||
end
|
||||
end,
|
||||
|
||||
--moved functions from blizzard faux scroll that are called from insecure code environment
|
||||
--this reduces the amount of taints while using the faux scroll frame
|
||||
GetOffsetFaux = function(self)
|
||||
return self.offset or 0
|
||||
end,
|
||||
OnVerticalScrollFaux = function(self, value, itemHeight, updateFunction)
|
||||
local scrollbar = self:GetChildFramesFaux();
|
||||
scrollbar:SetValue(value);
|
||||
self.offset = math.floor((value / itemHeight) + 0.5);
|
||||
if (updateFunction) then
|
||||
updateFunction(self)
|
||||
end
|
||||
end,
|
||||
GetChildFramesFaux = function(frame)
|
||||
local frameName = frame:GetName();
|
||||
if frameName then
|
||||
return _G[ frameName.."ScrollBar" ], _G[ frameName.."ScrollChildFrame" ], _G[ frameName.."ScrollBarScrollUpButton" ], _G[ frameName.."ScrollBarScrollDownButton" ];
|
||||
else
|
||||
return frame.ScrollBar, frame.ScrollChildFrame, frame.ScrollBar.ScrollUpButton, frame.ScrollBar.ScrollDownButton;
|
||||
end
|
||||
end,
|
||||
UpdateFaux = function(frame, numItems, numToDisplay, buttonHeight, button, smallWidth, bigWidth, highlightFrame, smallHighlightWidth, bigHighlightWidth, alwaysShowScrollBar)
|
||||
local scrollBar, scrollChildFrame, scrollUpButton, scrollDownButton = frame:GetChildFramesFaux();
|
||||
-- If more than one screen full of items then show the scrollbar
|
||||
local showScrollBar;
|
||||
if ( numItems > numToDisplay or alwaysShowScrollBar ) then
|
||||
frame:Show();
|
||||
showScrollBar = 1;
|
||||
else
|
||||
scrollBar:SetValue(0);
|
||||
frame:Hide();
|
||||
end
|
||||
if ( frame:IsShown() ) then
|
||||
local scrollFrameHeight = 0;
|
||||
local scrollChildHeight = 0;
|
||||
|
||||
if ( numItems > 0 ) then
|
||||
scrollFrameHeight = (numItems - numToDisplay) * buttonHeight;
|
||||
scrollChildHeight = numItems * buttonHeight;
|
||||
if ( scrollFrameHeight < 0 ) then
|
||||
scrollFrameHeight = 0;
|
||||
end
|
||||
scrollChildFrame:Show();
|
||||
else
|
||||
scrollChildFrame:Hide();
|
||||
end
|
||||
local maxRange = (numItems - numToDisplay) * buttonHeight;
|
||||
if (maxRange < 0) then
|
||||
maxRange = 0;
|
||||
end
|
||||
scrollBar:SetMinMaxValues(0, maxRange);
|
||||
scrollBar:SetValueStep(buttonHeight);
|
||||
scrollBar:SetStepsPerPage(numToDisplay-1);
|
||||
scrollChildFrame:SetHeight(scrollChildHeight);
|
||||
|
||||
-- Arrow button handling
|
||||
if ( scrollBar:GetValue() == 0 ) then
|
||||
scrollUpButton:Disable();
|
||||
else
|
||||
scrollUpButton:Enable();
|
||||
end
|
||||
if ((scrollBar:GetValue() - scrollFrameHeight) == 0) then
|
||||
scrollDownButton:Disable();
|
||||
else
|
||||
scrollDownButton:Enable();
|
||||
end
|
||||
|
||||
-- Shrink because scrollbar is shown
|
||||
if ( highlightFrame ) then
|
||||
highlightFrame:SetWidth(smallHighlightWidth);
|
||||
end
|
||||
if ( button ) then
|
||||
for i=1, numToDisplay do
|
||||
_G[button..i]:SetWidth(smallWidth);
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Widen because scrollbar is hidden
|
||||
if ( highlightFrame ) then
|
||||
highlightFrame:SetWidth(bigHighlightWidth);
|
||||
end
|
||||
if ( button ) then
|
||||
for i=1, numToDisplay do
|
||||
_G[button..i]:SetWidth(bigWidth);
|
||||
end
|
||||
end
|
||||
end
|
||||
return showScrollBar;
|
||||
end,
|
||||
}
|
||||
|
||||
--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 DetailsFramework.SortFunctions
|
||||
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,
|
||||
}
|
||||
@@ -1,861 +0,0 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local _unpack = unpack
|
||||
local type = type
|
||||
local _math_floor = math.floor
|
||||
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local APIBarFunctions
|
||||
|
||||
do
|
||||
local metaPrototype = {
|
||||
WidgetType = "normal_bar",
|
||||
dversion = DF.dversion,
|
||||
}
|
||||
|
||||
--check if there's a metaPrototype already existing
|
||||
if (_G[DF.GlobalWidgetControlNames["normal_bar"]]) then
|
||||
--get the already existing metaPrototype
|
||||
local oldMetaPrototype = _G[DF.GlobalWidgetControlNames["normal_bar"]]
|
||||
--check if is older
|
||||
if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < DF.dversion) ) then
|
||||
--the version is older them the currently loading one
|
||||
--copy the new values into the old metatable
|
||||
for funcName, _ in pairs(metaPrototype) do
|
||||
oldMetaPrototype[funcName] = metaPrototype[funcName]
|
||||
end
|
||||
end
|
||||
else
|
||||
--first time loading the framework
|
||||
_G[DF.GlobalWidgetControlNames["normal_bar"]] = metaPrototype
|
||||
end
|
||||
end
|
||||
|
||||
local BarMetaFunctions = _G[DF.GlobalWidgetControlNames["normal_bar"]]
|
||||
DF:Mixin(BarMetaFunctions, DF.ScriptHookMixin)
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--metatables
|
||||
|
||||
BarMetaFunctions.__call = function(object, value)
|
||||
if (not value) then
|
||||
return object.statusbar:GetValue()
|
||||
else
|
||||
return object.statusbar:SetValue(value)
|
||||
end
|
||||
end
|
||||
|
||||
BarMetaFunctions.__add = function(v1, v2)
|
||||
if (type(v1) == "table") then
|
||||
local v = v1.statusbar:GetValue()
|
||||
v = v + v2
|
||||
v1.statusbar:SetValue(v)
|
||||
else
|
||||
local v = v2.statusbar:GetValue()
|
||||
v = v + v1
|
||||
v2.statusbar:SetValue(v)
|
||||
end
|
||||
end
|
||||
|
||||
BarMetaFunctions.__sub = function(v1, v2)
|
||||
if (type(v1) == "table") then
|
||||
local v = v1.statusbar:GetValue()
|
||||
v = v - v2
|
||||
v1.statusbar:SetValue(v)
|
||||
else
|
||||
local v = v2.statusbar:GetValue()
|
||||
v = v - v1
|
||||
v2.statusbar:SetValue(v)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--members
|
||||
|
||||
--tooltip
|
||||
local function gmember_tooltip (_object)
|
||||
return _object:GetTooltip()
|
||||
end
|
||||
--shown
|
||||
local gmember_shown = function(_object)
|
||||
return _object.statusbar:IsShown()
|
||||
end
|
||||
--frame width
|
||||
local gmember_width = function(_object)
|
||||
return _object.statusbar:GetWidth()
|
||||
end
|
||||
--frame height
|
||||
local gmember_height = function(_object)
|
||||
return _object.statusbar:GetHeight()
|
||||
end
|
||||
--value
|
||||
local gmember_value = function(_object)
|
||||
return _object.statusbar:GetValue()
|
||||
end
|
||||
--right text
|
||||
local gmember_rtext = function(_object)
|
||||
return _object.textright:GetText()
|
||||
end
|
||||
--left text
|
||||
local gmember_ltext = function(_object)
|
||||
return _object.textleft:GetText()
|
||||
end
|
||||
--left color
|
||||
local gmember_color = function(_object)
|
||||
local r, g, b, a = _object._texture:GetVertexColor()
|
||||
return r, g, b, a
|
||||
end
|
||||
--icon
|
||||
local gmember_icon = function(_object)
|
||||
return _object._icon:GetTexture()
|
||||
end
|
||||
--texture
|
||||
local gmember_texture = function(_object)
|
||||
return _object._texture:GetTexture()
|
||||
end
|
||||
--font size
|
||||
local gmember_textsize = function(_object)
|
||||
local _, fontsize = _object.textleft:GetFont()
|
||||
return fontsize
|
||||
end
|
||||
--font face
|
||||
local gmember_textfont = function(_object)
|
||||
local fontface = _object.textleft:GetFont()
|
||||
return fontface
|
||||
end
|
||||
--font color
|
||||
local gmember_textcolor = function(_object)
|
||||
return _object.textleft:GetTextColor()
|
||||
end
|
||||
--alpha
|
||||
local gmember_alpha= function(_object)
|
||||
return _object:GetAlpha()
|
||||
end
|
||||
|
||||
BarMetaFunctions.GetMembers = BarMetaFunctions.GetMembers or {}
|
||||
BarMetaFunctions.GetMembers ["tooltip"] = gmember_tooltip
|
||||
BarMetaFunctions.GetMembers ["shown"] = gmember_shown
|
||||
BarMetaFunctions.GetMembers ["width"] = gmember_width
|
||||
BarMetaFunctions.GetMembers ["height"] = gmember_height
|
||||
BarMetaFunctions.GetMembers ["value"] = gmember_value
|
||||
BarMetaFunctions.GetMembers ["lefttext"] = gmember_ltext
|
||||
BarMetaFunctions.GetMembers ["righttext"] = gmember_rtext
|
||||
BarMetaFunctions.GetMembers ["color"] = gmember_color
|
||||
BarMetaFunctions.GetMembers ["icon"] = gmember_icon
|
||||
BarMetaFunctions.GetMembers ["texture"] = gmember_texture
|
||||
BarMetaFunctions.GetMembers ["fontsize"] = gmember_textsize
|
||||
BarMetaFunctions.GetMembers ["fontface"] = gmember_textfont
|
||||
BarMetaFunctions.GetMembers ["fontcolor"] = gmember_textcolor
|
||||
BarMetaFunctions.GetMembers ["textsize"] = gmember_textsize --alias
|
||||
BarMetaFunctions.GetMembers ["textfont"] = gmember_textfont --alias
|
||||
BarMetaFunctions.GetMembers ["textcolor"] = gmember_textcolor --alias
|
||||
BarMetaFunctions.GetMembers ["alpha"] = gmember_alpha
|
||||
|
||||
BarMetaFunctions.__index = function(_table, _member_requested)
|
||||
|
||||
local func = BarMetaFunctions.GetMembers [_member_requested]
|
||||
if (func) then
|
||||
return func (_table, _member_requested)
|
||||
end
|
||||
|
||||
local fromMe = rawget (_table, _member_requested)
|
||||
if (fromMe) then
|
||||
return fromMe
|
||||
end
|
||||
|
||||
return BarMetaFunctions [_member_requested]
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
--tooltip
|
||||
local smember_tooltip = function(_object, _value)
|
||||
return _object:SetTooltip (_value)
|
||||
end
|
||||
--show
|
||||
local smember_shown = function(_object, _value)
|
||||
if (_value) then
|
||||
return _object:Show()
|
||||
else
|
||||
return _object:Hide()
|
||||
end
|
||||
end
|
||||
--hide
|
||||
local smember_hide = function(_object, _value)
|
||||
if (_value) then
|
||||
return _object:Hide()
|
||||
else
|
||||
return _object:Show()
|
||||
end
|
||||
end
|
||||
--width
|
||||
local smember_width = function(_object, _value)
|
||||
return _object.statusbar:SetWidth(_value)
|
||||
end
|
||||
--height
|
||||
local smember_height = function(_object, _value)
|
||||
return _object.statusbar:SetHeight(_value)
|
||||
end
|
||||
--statusbar value
|
||||
local smember_value = function(_object, _value)
|
||||
_object.statusbar:SetValue(_value)
|
||||
return _object.div:SetPoint("left", _object.statusbar, "left", _value * (_object.statusbar:GetWidth()/100) - 16, 0)
|
||||
end
|
||||
--right text
|
||||
local smember_rtext = function(_object, _value)
|
||||
return _object.textright:SetText(_value)
|
||||
end
|
||||
--left text
|
||||
local smember_ltext = function(_object, _value)
|
||||
return _object.textleft:SetText(_value)
|
||||
end
|
||||
--color
|
||||
local smember_color = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
|
||||
_object.statusbar:SetStatusBarColor(_value1, _value2, _value3, _value4)
|
||||
_object._texture.original_colors = {_value1, _value2, _value3, _value4}
|
||||
_object.timer_texture:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
|
||||
_object.timer_textureR:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
|
||||
return _object._texture:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
--background color
|
||||
local smember_backgroundcolor = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
return _object.background:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
--icon
|
||||
local smember_icon = function(_object, _value)
|
||||
if (type(_value) == "table") then
|
||||
local _value1, _value2 = _unpack(_value)
|
||||
_object._icon:SetTexture(_value1)
|
||||
if (_value2) then
|
||||
_object._icon:SetTexCoord(_unpack(_value2))
|
||||
end
|
||||
else
|
||||
_object._icon:SetTexture(_value)
|
||||
end
|
||||
return
|
||||
end
|
||||
--texture
|
||||
local smember_texture = function(_object, _value)
|
||||
if (type(_value) == "table") then
|
||||
local _value1, _value2 = _unpack(_value)
|
||||
_object._texture:SetTexture(_value1)
|
||||
_object.timer_texture:SetTexture(_value1)
|
||||
_object.timer_textureR:SetTexture(_value1)
|
||||
if (_value2) then
|
||||
_object._texture:SetTexCoord(_unpack(_value2))
|
||||
_object.timer_texture:SetTexCoord(_unpack(_value2))
|
||||
_object.timer_textureR:SetTexCoord(_unpack(_value2))
|
||||
end
|
||||
else
|
||||
if (_value:find("\\")) then
|
||||
_object._texture:SetTexture(_value)
|
||||
else
|
||||
local file = SharedMedia:Fetch ("statusbar", _value)
|
||||
if (file) then
|
||||
_object._texture:SetTexture(file)
|
||||
_object.timer_texture:SetTexture(file)
|
||||
_object.timer_textureR:SetTexture(file)
|
||||
else
|
||||
_object._texture:SetTexture(_value)
|
||||
_object.timer_texture:SetTexture(_value)
|
||||
_object.timer_textureR:SetTexture(_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
--background texture
|
||||
local smember_backgroundtexture = function(_object, _value)
|
||||
if (_value:find("\\")) then
|
||||
_object.background:SetTexture(_value)
|
||||
else
|
||||
local file = SharedMedia:Fetch ("statusbar", _value)
|
||||
if (file) then
|
||||
_object.background:SetTexture(file)
|
||||
else
|
||||
_object.background:SetTexture(_value)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
--font face
|
||||
local smember_textfont = function(_object, _value)
|
||||
DF:SetFontFace (_object.textleft, _value)
|
||||
return DF:SetFontFace (_object.textright, _value)
|
||||
end
|
||||
--font size
|
||||
local smember_textsize = function(_object, _value)
|
||||
DF:SetFontSize(_object.textleft, _value)
|
||||
return DF:SetFontSize(_object.textright, _value)
|
||||
end
|
||||
--font color
|
||||
local smember_textcolor = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
_object.textleft:SetTextColor(_value1, _value2, _value3, _value4)
|
||||
return _object.textright:SetTextColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
--outline (shadow)
|
||||
local smember_outline = function(_object, _value)
|
||||
DF:SetFontOutline (_object.textleft, _value)
|
||||
return DF:SetFontOutline (_object.textright, _value)
|
||||
end
|
||||
--alpha
|
||||
local smember_alpha= function(_object, _value)
|
||||
return _object:SetAlpha(_value)
|
||||
end
|
||||
|
||||
BarMetaFunctions.SetMembers = BarMetaFunctions.SetMembers or {}
|
||||
BarMetaFunctions.SetMembers["tooltip"] = smember_tooltip
|
||||
BarMetaFunctions.SetMembers["shown"] = smember_shown
|
||||
BarMetaFunctions.SetMembers["width"] = smember_width
|
||||
BarMetaFunctions.SetMembers["height"] = smember_height
|
||||
BarMetaFunctions.SetMembers["value"] = smember_value
|
||||
BarMetaFunctions.SetMembers["righttext"] = smember_rtext
|
||||
BarMetaFunctions.SetMembers["lefttext"] = smember_ltext
|
||||
BarMetaFunctions.SetMembers["color"] = smember_color
|
||||
BarMetaFunctions.SetMembers["backgroundcolor"] = smember_backgroundcolor
|
||||
BarMetaFunctions.SetMembers["icon"] = smember_icon
|
||||
BarMetaFunctions.SetMembers["texture"] = smember_texture
|
||||
BarMetaFunctions.SetMembers["backgroundtexture"] = smember_backgroundtexture
|
||||
BarMetaFunctions.SetMembers["fontsize"] = smember_textsize
|
||||
BarMetaFunctions.SetMembers["fontface"] = smember_textfont
|
||||
BarMetaFunctions.SetMembers["fontcolor"] = smember_textcolor
|
||||
BarMetaFunctions.SetMembers["textsize"] = smember_textsize --alias
|
||||
BarMetaFunctions.SetMembers["textfont"] = smember_textfont --alias
|
||||
BarMetaFunctions.SetMembers["textcolor"] = smember_textcolor --alias
|
||||
BarMetaFunctions.SetMembers["shadow"] = smember_outline
|
||||
BarMetaFunctions.SetMembers["outline"] = smember_outline --alias
|
||||
BarMetaFunctions.SetMembers["alpha"] = smember_alpha
|
||||
|
||||
BarMetaFunctions.__newindex = function(_table, _key, _value)
|
||||
|
||||
local func = BarMetaFunctions.SetMembers [_key]
|
||||
if (func) then
|
||||
return func (_table, _value)
|
||||
else
|
||||
return rawset (_table, _key, _value)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--methods
|
||||
|
||||
--show & hide
|
||||
function BarMetaFunctions:Show()
|
||||
self.statusbar:Show()
|
||||
end
|
||||
function BarMetaFunctions:Hide()
|
||||
self.statusbar:Hide()
|
||||
end
|
||||
|
||||
|
||||
--return color
|
||||
function BarMetaFunctions:GetVertexColor()
|
||||
return self._texture:GetVertexColor()
|
||||
end
|
||||
|
||||
--set value (status bar)
|
||||
|
||||
function BarMetaFunctions:SetValue(value)
|
||||
if (not value) then
|
||||
value = 0
|
||||
end
|
||||
self.statusbar:SetValue(value)
|
||||
self.div:SetPoint("left", self.statusbar, "left", value * (self.statusbar:GetWidth()/100) - 16, 0)
|
||||
end
|
||||
|
||||
--set point
|
||||
function BarMetaFunctions:SetPoint(v1, v2, v3, v4, v5)
|
||||
v1, v2, v3, v4, v5 = DF:CheckPoints (v1, v2, v3, v4, v5, self)
|
||||
if (not v1) then
|
||||
print("Invalid parameter for SetPoint")
|
||||
return
|
||||
end
|
||||
return self.widget:SetPoint(v1, v2, v3, v4, v5)
|
||||
end
|
||||
|
||||
--set sizes
|
||||
function BarMetaFunctions:SetSize(w, h)
|
||||
if (w) then
|
||||
self.statusbar:SetWidth(w)
|
||||
end
|
||||
if (h) then
|
||||
self.statusbar:SetHeight(h)
|
||||
end
|
||||
end
|
||||
|
||||
--set texture
|
||||
function BarMetaFunctions:SetTexture(texture)
|
||||
self._texture:SetTexture(texture)
|
||||
end
|
||||
|
||||
--set texts
|
||||
function BarMetaFunctions:SetLeftText (text)
|
||||
self.textleft:SetText(text)
|
||||
end
|
||||
function BarMetaFunctions:SetRightText (text)
|
||||
self.textright:SetText(text)
|
||||
end
|
||||
|
||||
--set color
|
||||
function BarMetaFunctions:SetColor (r, g, b, a)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
|
||||
self._texture:SetVertexColor(r, g, b, a)
|
||||
self.statusbar:SetStatusBarColor(r, g, b, a)
|
||||
self._texture.original_colors = {r, g, b, a}
|
||||
end
|
||||
|
||||
--set icons
|
||||
function BarMetaFunctions:SetIcon (texture, ...)
|
||||
self._icon:SetTexture(texture)
|
||||
if (...) then
|
||||
local L, R, U, D = _unpack(...)
|
||||
self._icon:SetTexCoord(L, R, U, D)
|
||||
end
|
||||
end
|
||||
|
||||
--show div
|
||||
function BarMetaFunctions:ShowDiv (bool)
|
||||
if (bool) then
|
||||
self.div:Show()
|
||||
else
|
||||
self.div:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- tooltip
|
||||
function BarMetaFunctions:SetTooltip (tooltip)
|
||||
if (tooltip) then
|
||||
return rawset (self, "have_tooltip", tooltip)
|
||||
else
|
||||
return rawset (self, "have_tooltip", nil)
|
||||
end
|
||||
end
|
||||
function BarMetaFunctions:GetTooltip()
|
||||
return rawget (self, "have_tooltip")
|
||||
end
|
||||
|
||||
-- frame levels
|
||||
function BarMetaFunctions:GetFrameLevel()
|
||||
return self.statusbar:GetFrameLevel()
|
||||
end
|
||||
function BarMetaFunctions:SetFrameLevel(level, frame)
|
||||
if (not frame) then
|
||||
return self.statusbar:SetFrameLevel(level)
|
||||
else
|
||||
local framelevel = frame:GetFrameLevel (frame) + level
|
||||
return self.statusbar:SetFrameLevel(framelevel)
|
||||
end
|
||||
end
|
||||
|
||||
-- frame stratas
|
||||
function BarMetaFunctions:SetFrameStrata()
|
||||
return self.statusbar:GetFrameStrata()
|
||||
end
|
||||
function BarMetaFunctions:SetFrameStrata(strata)
|
||||
if (type(strata) == "table") then
|
||||
self.statusbar:SetFrameStrata(strata:GetFrameStrata())
|
||||
else
|
||||
self.statusbar:SetFrameStrata(strata)
|
||||
end
|
||||
end
|
||||
|
||||
--container
|
||||
function BarMetaFunctions:SetContainer (container)
|
||||
self.container = container
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--scripts
|
||||
|
||||
local OnEnter = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnEnter", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
frame.MyObject.background:Show()
|
||||
|
||||
if (frame.MyObject.have_tooltip) then
|
||||
GameCooltip2:Reset()
|
||||
GameCooltip2:AddLine(frame.MyObject.have_tooltip)
|
||||
GameCooltip2:ShowCooltip(frame, "tooltip")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local OnLeave = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnLeave", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
frame.MyObject.background:Hide()
|
||||
|
||||
if (frame.MyObject.have_tooltip) then
|
||||
GameCooltip2:ShowMe(false)
|
||||
end
|
||||
end
|
||||
|
||||
local OnHide = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnHide", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnShow = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnShow", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseDown = function(frame, button)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnMouseDown", frame, button, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (not frame.MyObject.container.isLocked and frame.MyObject.container:IsMovable()) then
|
||||
if (not frame.isLocked and frame:IsMovable()) then
|
||||
frame.MyObject.container.isMoving = true
|
||||
frame.MyObject.container:StartMoving()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseUp = function(frame, button)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnMouseUp", frame, button, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (frame.MyObject.container.isMoving) then
|
||||
frame.MyObject.container:StopMovingOrSizing()
|
||||
frame.MyObject.container.isMoving = false
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--timer
|
||||
|
||||
function BarMetaFunctions:OnTimerEnd()
|
||||
local capsule = self
|
||||
local kill = capsule:RunHooksForWidget("OnTimerEnd", self.widget, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
self.timer_texture:Hide()
|
||||
self.timer_textureR:Hide()
|
||||
self.div_timer:Hide()
|
||||
self:Hide()
|
||||
self.timer = false
|
||||
end
|
||||
|
||||
function BarMetaFunctions:CancelTimerBar(no_timer_end)
|
||||
if (not self.HasTimer) then
|
||||
return
|
||||
end
|
||||
if (self.TimerScheduled) then
|
||||
DF:CancelTimer(self.TimerScheduled)
|
||||
self.TimerScheduled = nil
|
||||
else
|
||||
if (self.statusbar:GetScript("OnUpdate")) then
|
||||
self.statusbar:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
|
||||
self.righttext = ""
|
||||
self.timer_texture:Hide()
|
||||
self.timer_textureR:Hide()
|
||||
|
||||
if (not no_timer_end) then
|
||||
self:OnTimerEnd()
|
||||
end
|
||||
end
|
||||
|
||||
local OnUpdate = function(self, elapsed)
|
||||
--percent of elapsed
|
||||
local pct = abs(self.end_timer - GetTime() - self.tempo) / self.tempo
|
||||
|
||||
if (self.inverse) then
|
||||
self.t:SetWidth(self.total_size * pct)
|
||||
else
|
||||
self.t:SetWidth(self.total_size * abs(pct-1))
|
||||
end
|
||||
|
||||
--right text
|
||||
self.remaining = self.remaining - elapsed
|
||||
if (self.MyObject.RightTextIsTimer) then
|
||||
self.righttext:SetText(DF:IntegerToTimer(self.remaining))
|
||||
else
|
||||
self.righttext:SetText(_math_floor(self.remaining))
|
||||
end
|
||||
|
||||
if (pct >= 1) then
|
||||
self.righttext:SetText("")
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self.MyObject.HasTimer = nil
|
||||
self.MyObject:OnTimerEnd()
|
||||
end
|
||||
end
|
||||
|
||||
function BarMetaFunctions:SetTimer (tempo, end_at)
|
||||
if (end_at) then
|
||||
self.statusbar.tempo = end_at - tempo
|
||||
self.statusbar.remaining = end_at - GetTime()
|
||||
self.statusbar.end_timer = end_at
|
||||
else
|
||||
self.statusbar.tempo = tempo
|
||||
self.statusbar.remaining = tempo
|
||||
self.statusbar.end_timer = GetTime() + tempo
|
||||
end
|
||||
|
||||
self.statusbar.total_size = self.statusbar:GetWidth()
|
||||
self.statusbar.inverse = self.BarIsInverse
|
||||
|
||||
self(0)
|
||||
|
||||
self.div_timer:Show()
|
||||
self.background:Show()
|
||||
self:Show()
|
||||
|
||||
if (self.LeftToRight) then
|
||||
self.timer_texture:Hide()
|
||||
self.timer_textureR:Show()
|
||||
self.statusbar.t = self.timer_textureR
|
||||
self.timer_textureR:ClearAllPoints()
|
||||
self.timer_textureR:SetPoint("right", self.statusbar, "right")
|
||||
self.div_timer:SetPoint("left", self.timer_textureR, "left", -14, -1)
|
||||
else
|
||||
self.timer_texture:Show()
|
||||
self.timer_textureR:Hide()
|
||||
self.statusbar.t = self.timer_texture
|
||||
self.timer_texture:ClearAllPoints()
|
||||
self.timer_texture:SetPoint("left", self.statusbar, "left")
|
||||
self.div_timer:SetPoint("left", self.timer_texture, "right", -16, -1)
|
||||
end
|
||||
|
||||
if (self.BarIsInverse) then
|
||||
self.statusbar.t:SetWidth(1)
|
||||
else
|
||||
self.statusbar.t:SetWidth(self.statusbar.total_size)
|
||||
end
|
||||
|
||||
self.timer = true
|
||||
|
||||
self.HasTimer = true
|
||||
self.TimerScheduled = DF:ScheduleTimer("StartTimeBarAnimation", 0.1, self)
|
||||
end
|
||||
|
||||
function DF:StartTimeBarAnimation (timebar)
|
||||
timebar.TimerScheduled = nil
|
||||
timebar.statusbar:SetScript("OnUpdate", OnUpdate)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--object constructor
|
||||
|
||||
function DetailsFrameworkNormalBar_OnCreate (self)
|
||||
self.texture.original_colors = {1, 1, 1, 1}
|
||||
self.background.original_colors = {.3, .3, .3, .3}
|
||||
self.timertexture.original_colors = {.3, .3, .3, .3}
|
||||
return true
|
||||
end
|
||||
|
||||
local build_statusbar = function(self)
|
||||
|
||||
self:SetSize(300, 14)
|
||||
|
||||
self.background = self:CreateTexture("$parent_background", "BACKGROUND")
|
||||
self.background:Hide()
|
||||
self.background:SetAllPoints()
|
||||
self.background:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
self.background:SetVertexColor(.3, .3, .3, .3)
|
||||
|
||||
self.timertexture = self:CreateTexture("$parent_timerTexture", "ARTWORK")
|
||||
self.timertexture:Hide()
|
||||
self.timertexture:SetSize(300, 14)
|
||||
self.timertexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
self.timertexture:SetPoint("LEFT", self, "LEFT")
|
||||
|
||||
self.timertextureR = self:CreateTexture("$parent_timerTextureR", "ARTWORK")
|
||||
self.timertextureR:Hide()
|
||||
self.timertextureR:SetSize(300, 14)
|
||||
self.timertextureR:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
self.timertextureR:SetPoint("TOPRIGHT", self, 0, 0)
|
||||
self.timertextureR:SetPoint("BOTTOMRIGHT", self, 0, 0)
|
||||
|
||||
self.texture = self:CreateTexture("$parent_statusbarTexture", "ARTWORK")
|
||||
self.texture:SetSize(300, 14)
|
||||
self.texture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
|
||||
self:SetStatusBarTexture(self.texture)
|
||||
|
||||
self.icontexture = self:CreateTexture("$parent_icon", "OVERLAY")
|
||||
self.icontexture:SetSize(14, 14)
|
||||
self.icontexture:SetPoint("LEFT", self, "LEFT")
|
||||
|
||||
self.sparkmouseover = self:CreateTexture("$parent_sparkMouseover", "OVERLAY")
|
||||
self.sparkmouseover:SetSize(32, 32)
|
||||
self.sparkmouseover:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
self.sparkmouseover:SetBlendMode("ADD")
|
||||
self.sparkmouseover:SetPoint("LEFT", self, "RIGHT", -16, -1)
|
||||
self.sparkmouseover:Hide()
|
||||
|
||||
self.sparktimer = self:CreateTexture("$parent_sparkTimer", "OVERLAY")
|
||||
self.sparktimer:SetSize(32, 32)
|
||||
self.sparktimer:SetPoint("LEFT", self.timertexture, "RIGHT", -16, -1)
|
||||
self.sparktimer:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
self.sparktimer:SetBlendMode("ADD")
|
||||
self.sparktimer:Hide()
|
||||
|
||||
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)
|
||||
|
||||
self.righttext = self:CreateFontString("$parent_TextRight", "OVERLAY", "GameFontHighlight")
|
||||
self.righttext:SetJustifyH("LEFT")
|
||||
DF:SetFontSize(self.righttext, 10)
|
||||
self.righttext:SetPoint("RIGHT", self, "RIGHT", -3, 0)
|
||||
|
||||
DetailsFrameworkNormalBar_OnCreate (self)
|
||||
end
|
||||
|
||||
function DF:CreateBar (parent, texture, w, h, value, member, name)
|
||||
return DF:NewBar (parent, parent, name, member, w, h, value, texture)
|
||||
end
|
||||
|
||||
function DF:NewBar (parent, container, name, member, w, h, value, texture_name)
|
||||
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkBarNumber" .. DF.BarNameCounter
|
||||
DF.BarNameCounter = DF.BarNameCounter + 1
|
||||
|
||||
elseif (not parent) then
|
||||
return error("Details! FrameWork: parent not found.", 2)
|
||||
elseif (not container) then
|
||||
container = parent
|
||||
end
|
||||
|
||||
if (name:find("$parent")) then
|
||||
local parentName = DF.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
|
||||
local BarObject = {type = "bar", dframework = true}
|
||||
|
||||
if (member) then
|
||||
parent [member] = BarObject
|
||||
end
|
||||
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
if (container.dframework) then
|
||||
container = container.widget
|
||||
end
|
||||
|
||||
value = value or 0
|
||||
w = w or 150
|
||||
h = h or 14
|
||||
|
||||
--default members:
|
||||
--misc
|
||||
BarObject.locked = false
|
||||
|
||||
BarObject.container = container
|
||||
|
||||
--create widgets
|
||||
BarObject.statusbar = CreateFrame("statusbar", name, parent)
|
||||
DF:Mixin(BarObject.statusbar, DF.WidgetFunctions)
|
||||
|
||||
build_statusbar (BarObject.statusbar)
|
||||
|
||||
BarObject.widget = BarObject.statusbar
|
||||
|
||||
if (not APIBarFunctions) then
|
||||
APIBarFunctions = true
|
||||
local idx = getmetatable(BarObject.statusbar).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not BarMetaFunctions [funcName]) then
|
||||
BarMetaFunctions [funcName] = function(object, ...)
|
||||
local x = loadstring ( "return _G['"..object.statusbar:GetName().."']:"..funcName.."(...)")
|
||||
return x (...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BarObject.statusbar:SetHeight(h)
|
||||
BarObject.statusbar:SetWidth(w)
|
||||
BarObject.statusbar:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
BarObject.statusbar:SetMinMaxValues(0, 100)
|
||||
BarObject.statusbar:SetValue(value or 50)
|
||||
BarObject.statusbar.MyObject = BarObject
|
||||
|
||||
BarObject.timer_texture = _G [name .. "_timerTexture"]
|
||||
BarObject.timer_texture:SetWidth(w)
|
||||
BarObject.timer_texture:SetHeight(h)
|
||||
|
||||
BarObject.timer_textureR = _G [name .. "_timerTextureR"]
|
||||
BarObject.timer_textureR:Hide()
|
||||
|
||||
BarObject._texture = _G [name .. "_statusbarTexture"]
|
||||
BarObject.background = _G [name .. "_background"]
|
||||
BarObject._icon = _G [name .. "_icon"]
|
||||
BarObject.textleft = _G [name .. "_TextLeft"]
|
||||
BarObject.textright = _G [name .. "_TextRight"]
|
||||
BarObject.div = _G [name .. "_sparkMouseover"]
|
||||
BarObject.div_timer = _G [name .. "_sparkTimer"]
|
||||
|
||||
--hooks
|
||||
BarObject.HookList = {
|
||||
OnEnter = {},
|
||||
OnLeave = {},
|
||||
OnHide = {},
|
||||
OnShow = {},
|
||||
OnMouseDown = {},
|
||||
OnMouseUp = {},
|
||||
OnTimerEnd = {},
|
||||
}
|
||||
|
||||
BarObject.statusbar:SetScript("OnEnter", OnEnter)
|
||||
BarObject.statusbar:SetScript("OnLeave", OnLeave)
|
||||
BarObject.statusbar:SetScript("OnHide", OnHide)
|
||||
BarObject.statusbar:SetScript("OnShow", OnShow)
|
||||
BarObject.statusbar:SetScript("OnMouseDown", OnMouseDown)
|
||||
BarObject.statusbar:SetScript("OnMouseUp", OnMouseUp)
|
||||
|
||||
--set class
|
||||
setmetatable(BarObject, BarMetaFunctions)
|
||||
|
||||
--set texture
|
||||
if (texture_name) then
|
||||
smember_texture (BarObject, texture_name)
|
||||
end
|
||||
|
||||
return BarObject
|
||||
end --endd
|
||||
@@ -1,3 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
<Script file="normal_bar.lua"/>
|
||||
</Ui>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
<Script file="panel.lua"/>
|
||||
</Ui>
|
||||
@@ -1,369 +0,0 @@
|
||||
|
||||
local detailsFramework = _G["DetailsFramework"]
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local APIImageFunctions = false
|
||||
|
||||
do
|
||||
local metaPrototype = {
|
||||
WidgetType = "image",
|
||||
dversion = detailsFramework.dversion,
|
||||
}
|
||||
|
||||
--check if there's a metaPrototype already existing
|
||||
if (_G[detailsFramework.GlobalWidgetControlNames["image"]]) then
|
||||
--get the already existing metaPrototype
|
||||
local oldMetaPrototype = _G[detailsFramework.GlobalWidgetControlNames["image"]]
|
||||
--check if is older
|
||||
if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < detailsFramework.dversion) ) then
|
||||
--the version is older them the currently loading one
|
||||
--copy the new values into the old metatable
|
||||
for funcName, _ in pairs(metaPrototype) do
|
||||
oldMetaPrototype[funcName] = metaPrototype[funcName]
|
||||
end
|
||||
end
|
||||
else
|
||||
--first time loading the framework
|
||||
_G[detailsFramework.GlobalWidgetControlNames["image"]] = metaPrototype
|
||||
end
|
||||
end
|
||||
|
||||
local ImageMetaFunctions = _G[detailsFramework.GlobalWidgetControlNames["image"]]
|
||||
|
||||
detailsFramework:Mixin(ImageMetaFunctions, detailsFramework.SetPointMixin)
|
||||
detailsFramework:Mixin(ImageMetaFunctions, detailsFramework.ScriptHookMixin)
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--metatables
|
||||
|
||||
ImageMetaFunctions.__call = function(object, value)
|
||||
return object.image:SetTexture(value)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--members
|
||||
|
||||
--frame width
|
||||
local gmember_width = function(object)
|
||||
return object.image:GetWidth()
|
||||
end
|
||||
|
||||
--frame height
|
||||
local gmember_height = function(object)
|
||||
return object.image:GetHeight()
|
||||
end
|
||||
|
||||
--texture
|
||||
local gmember_texture = function(object)
|
||||
return object.image:GetTexture()
|
||||
end
|
||||
|
||||
--alpha
|
||||
local gmember_alpha = function(object)
|
||||
return object.image:GetAlpha()
|
||||
end
|
||||
|
||||
--saturation
|
||||
local gmember_saturation = function(object)
|
||||
return object.image:GetDesaturated()
|
||||
end
|
||||
|
||||
--atlas
|
||||
local gmember_atlas = function(object)
|
||||
return object.image:GetAtlas()
|
||||
end
|
||||
|
||||
--texcoords
|
||||
local gmember_texcoord = function(object)
|
||||
return object.image:GetTexCoord()
|
||||
end
|
||||
|
||||
ImageMetaFunctions.GetMembers = ImageMetaFunctions.GetMembers or {}
|
||||
detailsFramework:Mixin(ImageMetaFunctions.GetMembers, detailsFramework.DefaultMetaFunctionsGet)
|
||||
detailsFramework:Mixin(ImageMetaFunctions.GetMembers, detailsFramework.LayeredRegionMetaFunctionsGet)
|
||||
|
||||
ImageMetaFunctions.GetMembers["alpha"] = gmember_alpha
|
||||
ImageMetaFunctions.GetMembers["width"] = gmember_width
|
||||
ImageMetaFunctions.GetMembers["height"] = gmember_height
|
||||
ImageMetaFunctions.GetMembers["texture"] = gmember_texture
|
||||
ImageMetaFunctions.GetMembers["blackwhite"] = gmember_saturation
|
||||
ImageMetaFunctions.GetMembers["desaturated"] = gmember_saturation
|
||||
ImageMetaFunctions.GetMembers["atlas"] = gmember_atlas
|
||||
ImageMetaFunctions.GetMembers["texcoord"] = gmember_texcoord
|
||||
|
||||
ImageMetaFunctions.__index = function(object, key)
|
||||
local func = ImageMetaFunctions.GetMembers[key]
|
||||
if (func) then
|
||||
return func(object, key)
|
||||
end
|
||||
|
||||
local fromMe = rawget(object, key)
|
||||
if (fromMe) then
|
||||
return fromMe
|
||||
end
|
||||
|
||||
return ImageMetaFunctions[key]
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--texture
|
||||
local smember_texture = function(object, value)
|
||||
if (type(value) == "table") then
|
||||
local red, green, blue, alpha = detailsFramework:ParseColors(value)
|
||||
object.image:SetTexture(red, green, blue, alpha)
|
||||
else
|
||||
if (detailsFramework:IsHtmlColor(value)) then
|
||||
local red, green, blue, alpha = detailsFramework:ParseColors(value)
|
||||
object.image:SetTexture(red, green, blue, alpha)
|
||||
else
|
||||
object.image:SetTexture(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--width
|
||||
local smember_width = function(object, value)
|
||||
return object.image:SetWidth(value)
|
||||
end
|
||||
|
||||
--height
|
||||
local smember_height = function(object, value)
|
||||
return object.image:SetHeight(value)
|
||||
end
|
||||
|
||||
--alpha
|
||||
local smember_alpha = function(object, value)
|
||||
return object.image:SetAlpha(value)
|
||||
end
|
||||
|
||||
--color
|
||||
local smember_color = function(object, value)
|
||||
local red, green, blue, alpha = detailsFramework:ParseColors(value)
|
||||
object.image:SetColorTexture(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
--vertex color
|
||||
local smember_vertexcolor = function(object, value)
|
||||
local red, green, blue, alpha = detailsFramework:ParseColors(value)
|
||||
object.image:SetVertexColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
--desaturated
|
||||
local smember_desaturated = function(object, value)
|
||||
if (value) then
|
||||
object:SetDesaturated(true)
|
||||
else
|
||||
object:SetDesaturated(false)
|
||||
end
|
||||
end
|
||||
|
||||
--texcoords
|
||||
local smember_texcoord = function(object, value)
|
||||
if (value) then
|
||||
object:SetTexCoord(unpack(value))
|
||||
else
|
||||
object:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
--atlas
|
||||
local smember_atlas = function(object, value)
|
||||
if (value) then
|
||||
object:SetAtlas(value)
|
||||
end
|
||||
end
|
||||
|
||||
--gradient
|
||||
local smember_gradient = function(object, value)
|
||||
if (type(value) == "table" and value.gradient and value.fromColor and value.toColor) then
|
||||
object.image:SetColorTexture(1, 1, 1, 1)
|
||||
local fromColor = detailsFramework:FormatColor("tablemembers", value.fromColor)
|
||||
local toColor = detailsFramework:FormatColor("tablemembers", value.toColor)
|
||||
object.image:SetGradient(value.gradient, fromColor, toColor)
|
||||
else
|
||||
error("texture.gradient expect a table{gradient = 'gradient type', fromColor = 'color', toColor = 'color'}")
|
||||
end
|
||||
end
|
||||
|
||||
ImageMetaFunctions.SetMembers = ImageMetaFunctions.SetMembers or {}
|
||||
detailsFramework:Mixin(ImageMetaFunctions.SetMembers, detailsFramework.DefaultMetaFunctionsSet)
|
||||
detailsFramework:Mixin(ImageMetaFunctions.SetMembers, detailsFramework.LayeredRegionMetaFunctionsSet)
|
||||
|
||||
ImageMetaFunctions.SetMembers["alpha"] = smember_alpha
|
||||
ImageMetaFunctions.SetMembers["width"] = smember_width
|
||||
ImageMetaFunctions.SetMembers["height"] = smember_height
|
||||
ImageMetaFunctions.SetMembers["texture"] = smember_texture
|
||||
ImageMetaFunctions.SetMembers["texcoord"] = smember_texcoord
|
||||
ImageMetaFunctions.SetMembers["color"] = smember_color
|
||||
ImageMetaFunctions.SetMembers["vertexcolor"] = smember_vertexcolor
|
||||
ImageMetaFunctions.SetMembers["blackwhite"] = smember_desaturated
|
||||
ImageMetaFunctions.SetMembers["desaturated"] = smember_desaturated
|
||||
ImageMetaFunctions.SetMembers["atlas"] = smember_atlas
|
||||
ImageMetaFunctions.SetMembers["gradient"] = smember_gradient
|
||||
|
||||
ImageMetaFunctions.__newindex = function(object, key, value)
|
||||
local func = ImageMetaFunctions.SetMembers[key]
|
||||
if (func) then
|
||||
return func(object, value)
|
||||
else
|
||||
return rawset(object, key, value)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--methods
|
||||
--size
|
||||
function ImageMetaFunctions:SetSize(width, height)
|
||||
if (width) then
|
||||
self.image:SetWidth(width)
|
||||
end
|
||||
if (height) then
|
||||
return self.image:SetHeight(height)
|
||||
end
|
||||
end
|
||||
|
||||
function ImageMetaFunctions:SetGradient(gradientType, fromColor, toColor)
|
||||
fromColor = detailsFramework:FormatColor("tablemembers", fromColor)
|
||||
toColor = detailsFramework:FormatColor("tablemembers", toColor)
|
||||
self.image:SetGradient(gradientType, fromColor, toColor)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--object constructor
|
||||
|
||||
---@class df_image : texture
|
||||
---@field SetGradient fun(gradientType: "vertical"|"horizontal", fromColor: table, toColor: table)
|
||||
|
||||
---create an object that encapsulates a texture and add additional methods to it
|
||||
---@param parent frame
|
||||
---@param texture texturepath|textureid
|
||||
---@param width number
|
||||
---@param height number
|
||||
---@param layer drawlayer
|
||||
---@param coords {key1: number, key2: number, key3: number, key4: number}
|
||||
---@param member string
|
||||
---@param name string
|
||||
---@return table|nil
|
||||
function detailsFramework:CreateTexture(parent, texture, width, height, layer, coords, member, name)
|
||||
return detailsFramework:NewImage(parent, texture, width, height, layer, coords, member, name)
|
||||
end
|
||||
|
||||
---create an object that encapsulates a texture and add additional methods to it
|
||||
---@param parent frame
|
||||
---@param texture texturepath|textureid
|
||||
---@param width number
|
||||
---@param height number
|
||||
---@param layer drawlayer
|
||||
---@param coords {key1: number, key2: number, key3: number, key4: number}
|
||||
---@param member string
|
||||
---@param name string
|
||||
---@return table|nil
|
||||
function detailsFramework:CreateImage(parent, texture, width, height, layer, coords, member, name)
|
||||
return detailsFramework:NewImage(parent, texture, width, height, layer, coords, member, name)
|
||||
end
|
||||
|
||||
function detailsFramework:NewImage(parent, texture, width, height, layer, texCoord, member, name)
|
||||
if (not parent) then
|
||||
return error("DetailsFrameWork: NewImage() parent not found.", 2)
|
||||
end
|
||||
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkPictureNumber" .. detailsFramework.PictureNameCounter
|
||||
detailsFramework.PictureNameCounter = detailsFramework.PictureNameCounter + 1
|
||||
end
|
||||
|
||||
if (name:find("$parent")) then
|
||||
local parentName = detailsFramework.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
|
||||
local ImageObject = {type = "image", dframework = true}
|
||||
|
||||
if (member) then
|
||||
parent[member] = ImageObject
|
||||
end
|
||||
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
|
||||
texture = texture or ""
|
||||
|
||||
ImageObject.image = parent:CreateTexture(name, layer or "overlay")
|
||||
ImageObject.widget = ImageObject.image
|
||||
|
||||
detailsFramework:Mixin(ImageObject.image, detailsFramework.WidgetFunctions)
|
||||
|
||||
if (not APIImageFunctions) then
|
||||
APIImageFunctions = true
|
||||
local idx = getmetatable(ImageObject.image).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not ImageMetaFunctions[funcName]) then
|
||||
ImageMetaFunctions[funcName] = function(object, ...)
|
||||
local x = loadstring( "return _G['" .. object.image:GetName() .. "']:" .. funcName .. "(...)")
|
||||
return x(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ImageObject.image.MyObject = ImageObject
|
||||
|
||||
if (width) then
|
||||
ImageObject.image:SetWidth(width)
|
||||
end
|
||||
if (height) then
|
||||
ImageObject.image:SetHeight(height)
|
||||
end
|
||||
|
||||
if (texture) then
|
||||
if (type(texture) == "table") then
|
||||
if (texture.gradient) then
|
||||
if (detailsFramework.IsDragonflight() or detailsFramework.IsNonRetailWowWithRetailAPI()) then
|
||||
ImageObject.image:SetColorTexture(1, 1, 1, 1)
|
||||
local fromColor = detailsFramework:FormatColor("tablemembers", texture.fromColor)
|
||||
local toColor = detailsFramework:FormatColor("tablemembers", texture.toColor)
|
||||
ImageObject.image:SetGradient(texture.gradient, fromColor, toColor)
|
||||
else
|
||||
local fromR, fromG, fromB, fromA = detailsFramework:ParseColors(texture.fromColor)
|
||||
local toR, toG, toB, toA = detailsFramework:ParseColors(texture.toColor)
|
||||
ImageObject.image:SetColorTexture(1, 1, 1, 1)
|
||||
ImageObject.image:SetGradientAlpha(texture.gradient, fromR, fromG, fromB, fromA, toR, toG, toB, toA)
|
||||
end
|
||||
else
|
||||
local r, g, b, a = detailsFramework:ParseColors(texture)
|
||||
ImageObject.image:SetColorTexture(r, g, b, a)
|
||||
end
|
||||
|
||||
elseif (type(texture) == "string") then
|
||||
local isAtlas = C_Texture.GetAtlasInfo(texture)
|
||||
if (isAtlas) then
|
||||
ImageObject.image:SetAtlas(texture)
|
||||
else
|
||||
if (detailsFramework:IsHtmlColor(texture)) then
|
||||
local r, g, b = detailsFramework:ParseColors(texture)
|
||||
ImageObject.image:SetColorTexture(r, g, b)
|
||||
else
|
||||
ImageObject.image:SetTexture(texture)
|
||||
end
|
||||
end
|
||||
else
|
||||
ImageObject.image:SetTexture(texture)
|
||||
end
|
||||
end
|
||||
|
||||
if (texCoord and type(texCoord) == "table" and texCoord[4]) then
|
||||
ImageObject.image:SetTexCoord(unpack(texCoord))
|
||||
end
|
||||
|
||||
ImageObject.HookList = {
|
||||
}
|
||||
|
||||
setmetatable(ImageObject, ImageMetaFunctions)
|
||||
|
||||
return ImageObject
|
||||
end
|
||||
@@ -1,607 +0,0 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local texCoordinates
|
||||
|
||||
local CreateImageEditorFrame = function()
|
||||
local editorWindow = DF:NewPanel(UIParent, nil, "DetailsFrameworkImageEdit", nil, 650, 500, false)
|
||||
editorWindow:SetPoint("center", UIParent, "center")
|
||||
editorWindow:SetResizable(true)
|
||||
editorWindow:SetMovable(true)
|
||||
editorWindow:SetClampedToScreen(true)
|
||||
tinsert(UISpecialFrames, "DetailsFrameworkImageEdit")
|
||||
editorWindow:SetFrameStrata("TOOLTIP")
|
||||
|
||||
if (not DetailsFramework.IsDragonflight()) then
|
||||
editorWindow:SetMaxResize(500, 500)
|
||||
else
|
||||
editorWindow:SetResizeBounds(100, 100, 500, 500)
|
||||
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)
|
||||
background_frame:SetScript("OnMouseUp", function()
|
||||
editorWindow:StopMovingOrSizing()
|
||||
end)
|
||||
|
||||
DF:CreateTitleBar (background_frame, "Image Editor")
|
||||
DF:ApplyStandardBackdrop(background_frame, false, 0.98)
|
||||
DF:CreateStatusBar(background_frame)
|
||||
|
||||
background_frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
background_frame:SetBackdropColor(0, 0, 0, 0.9)
|
||||
background_frame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
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")
|
||||
topSlider.backdrop = nil
|
||||
topSlider.fractional = true
|
||||
topSlider:SetHook("OnEnter", function() return true end)
|
||||
topSlider:SetHook("OnLeave", function() return true end)
|
||||
|
||||
local topSliderThumpTexture = topSlider:CreateTexture(nil, "overlay")
|
||||
topSliderThumpTexture:SetColorTexture(1, 1, 1)
|
||||
topSliderThumpTexture:SetWidth(512)
|
||||
topSliderThumpTexture:SetHeight(1)
|
||||
topSlider:SetThumbTexture (topSliderThumpTexture)
|
||||
|
||||
topSlider:SetHook("OnValueChange", function(_, _, value)
|
||||
topCoordTexture.image:SetHeight(editorWindow.frame:GetHeight()/100*value)
|
||||
if (editorWindow.callback_func) then
|
||||
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)
|
||||
bottomCoordTexture:SetColorTexture(1, 0, 0)
|
||||
bottomCoordTexture.height = 1
|
||||
bottomCoordTexture.alpha = .2
|
||||
|
||||
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
|
||||
bottomSlider.fractional = true
|
||||
bottomSlider:SetHook("OnEnter", function() return true end)
|
||||
bottomSlider:SetHook("OnLeave", function() return true end)
|
||||
|
||||
local bottomSliderThumpTexture = bottomSlider:CreateTexture(nil, "overlay")
|
||||
bottomSliderThumpTexture:SetColorTexture(1, 1, 1)
|
||||
bottomSliderThumpTexture:SetWidth(512)
|
||||
bottomSliderThumpTexture:SetHeight(1)
|
||||
bottomSlider:SetThumbTexture (bottomSliderThumpTexture)
|
||||
|
||||
bottomSlider:SetHook("OnValueChange", function(_, _, value)
|
||||
value = math.abs(value-100)
|
||||
bottomCoordTexture.image:SetHeight(math.max(editorWindow.frame:GetHeight()/100*value, 1))
|
||||
if (editorWindow.callback_func) then
|
||||
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
|
||||
rightSlider.fractional = true
|
||||
rightSlider:SetHook("OnEnter", function() return true end)
|
||||
rightSlider:SetHook("OnLeave", function() return true end)
|
||||
--[
|
||||
local rightSliderThumpTexture = rightSlider:CreateTexture(nil, "overlay")
|
||||
rightSliderThumpTexture:SetColorTexture(1, 1, 1)
|
||||
rightSliderThumpTexture:SetWidth(1)
|
||||
rightSliderThumpTexture:SetHeight(512)
|
||||
rightSlider:SetThumbTexture (rightSliderThumpTexture)
|
||||
--]]
|
||||
rightSlider:SetHook("OnValueChange", function(_, _, value)
|
||||
value = math.abs(value-100)
|
||||
rightCoordTexture.image:SetWidth(math.max(editorWindow.frame:GetWidth()/100*value, 1))
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
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)
|
||||
buttonsBackground:Hide()
|
||||
--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
|
||||
|
||||
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)
|
||||
leftTexCoordButton:SetPoint("topright", buttonsBackground, "topright", -8, -10 + yMod)
|
||||
leftTexCoordButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
local rightTexCoordButton = DF:NewButton(buttonsBackground, nil, "$parentRightTexButton", nil, 100, 20, enableTexEdit, "right", nil, nil, "Crop Right", 1)
|
||||
rightTexCoordButton:SetPoint("topright", buttonsBackground, "topright", -8, -30 + yMod)
|
||||
rightTexCoordButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
local topTexCoordButton = DF:NewButton(buttonsBackground, nil, "$parentTopTexButton", nil, 100, 20, enableTexEdit, "top", nil, nil, "Crop Top", 1)
|
||||
topTexCoordButton:SetPoint("topright", buttonsBackground, "topright", -8, -50 + yMod)
|
||||
topTexCoordButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
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
|
||||
edit_texture:SetVertexColor(unpack(default))
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
else
|
||||
edit_texture:SetVertexColor(ColorPickerFrame:GetColorRGB())
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
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)
|
||||
ColorPickerFrame.hasOpacity = false
|
||||
ColorPickerFrame.previousValues = {right, g, bottom}
|
||||
ColorPickerFrame.func = selectedColor
|
||||
ColorPickerFrame.cancelFunc = selectedColor
|
||||
ColorPickerFrame:ClearAllPoints()
|
||||
ColorPickerFrame:SetPoint("left", buttonsBackground.widget, "right")
|
||||
ColorPickerFrame:Show()
|
||||
|
||||
if (alphaFrameShown) then
|
||||
alphaFrame:Hide()
|
||||
alphaFrameShown = false
|
||||
Alpha.button.text:SetTextColor(unpack(originalColor))
|
||||
end
|
||||
|
||||
if (lastButton) then
|
||||
lastButton.text:SetTextColor(unpack(originalColor))
|
||||
if (editingSide) then
|
||||
editorWindow [editingSide.."Slider"]:Hide()
|
||||
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()
|
||||
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)
|
||||
alphaFrameShown = true
|
||||
button.text:SetTextColor(1, 1, 1)
|
||||
else
|
||||
alphaFrame:Hide()
|
||||
alphaFrameShown = false
|
||||
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
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end)
|
||||
|
||||
local resizer = CreateFrame("Button", nil, editorWindow.widget, "BackdropTemplate")
|
||||
resizer:SetNormalTexture([[Interface\AddOns\Details\images\skins\default_skin]])
|
||||
resizer:SetHighlightTexture([[Interface\AddOns\Details\images\skins\default_skin]])
|
||||
resizer:GetNormalTexture():SetTexCoord(0.00146484375, 0.01513671875, 0.24560546875, 0.25927734375)
|
||||
resizer:GetHighlightTexture():SetTexCoord(0.00146484375, 0.01513671875, 0.24560546875, 0.25927734375)
|
||||
resizer:SetWidth(16)
|
||||
resizer:SetHeight(16)
|
||||
resizer:SetPoint("BOTTOMRIGHT", editorWindow.widget, "BOTTOMRIGHT", 0, 0)
|
||||
resizer:EnableMouse(true)
|
||||
resizer:SetFrameLevel(editorWindow.widget:GetFrameLevel() + 2)
|
||||
|
||||
resizer:SetScript("OnMouseDown", function(self, button)
|
||||
editorWindow.widget:StartSizing("BOTTOMRIGHT")
|
||||
end)
|
||||
|
||||
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
|
||||
leftSliderThumpTexture:SetHeight(editorWindow.height)
|
||||
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
|
||||
end)
|
||||
|
||||
--flip button
|
||||
local flip = function(button, bottom, side)
|
||||
if (side == 1) then
|
||||
haveHFlip = not haveHFlip
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
elseif (side == 2) then
|
||||
haveVFlip = not haveVFlip
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local flipButtonH = DF:NewButton(buttonsBackground, nil, "$parentFlipButton", nil, 100, 20, flip, 1, nil, nil, "Flip H", 1)
|
||||
flipButtonH:SetPoint("topright", buttonsBackground, "topright", -8, -140 + yMod)
|
||||
flipButtonH:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
--select area to crop
|
||||
local dragFrame = CreateFrame("frame", nil, background_frame, "BackdropTemplate")
|
||||
dragFrame:EnableMouse(false)
|
||||
dragFrame:SetFrameStrata("TOOLTIP")
|
||||
dragFrame:SetPoint("topleft", edit_texture.widget, "topleft")
|
||||
dragFrame:SetPoint("bottomright", edit_texture.widget, "bottomright")
|
||||
dragFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Worldmap\UI-QuestBlob-Inside]], tileSize = 256, tile = true})
|
||||
dragFrame:SetBackdropColor(1, 1, 1, .2)
|
||||
dragFrame:Hide()
|
||||
|
||||
local selectionBoxUp = dragFrame:CreateTexture(nil, "overlay")
|
||||
selectionBoxUp:SetHeight(1)
|
||||
selectionBoxUp:SetColorTexture(1, 1, 1)
|
||||
|
||||
local selectionBoxDown = dragFrame:CreateTexture(nil, "overlay")
|
||||
selectionBoxDown:SetHeight(1)
|
||||
selectionBoxDown:SetColorTexture(1, 1, 1)
|
||||
|
||||
local selectionBoxLeft = dragFrame:CreateTexture(nil, "overlay")
|
||||
selectionBoxLeft:SetWidth(1)
|
||||
selectionBoxLeft:SetColorTexture(1, 1, 1)
|
||||
|
||||
local selectionBoxRight = dragFrame:CreateTexture(nil, "overlay")
|
||||
selectionBoxRight:SetWidth(1)
|
||||
selectionBoxRight:SetColorTexture(1, 1, 1)
|
||||
|
||||
function dragFrame.ClearSelectionBoxPoints()
|
||||
selectionBoxUp:ClearAllPoints()
|
||||
selectionBoxDown:ClearAllPoints()
|
||||
selectionBoxLeft:ClearAllPoints()
|
||||
selectionBoxRight:ClearAllPoints()
|
||||
end
|
||||
|
||||
local startCropFunc = function()
|
||||
dragFrame:Show()
|
||||
dragFrame:EnableMouse(true)
|
||||
end
|
||||
|
||||
local cropSelection = DF:NewButton(buttonsBackground, nil, "$parentCropSelection", nil, 100, 20, startCropFunc, 2, nil, nil, "Crop Selection", 1)
|
||||
cropSelection:InstallCustomTexture()
|
||||
|
||||
dragFrame.OnTick = function(self, deltaTime)
|
||||
local x1, y1 = unpack(self.ClickedAt)
|
||||
local x2, y2 = GetCursorPosition()
|
||||
dragFrame.ClearSelectionBoxPoints()
|
||||
|
||||
if (x2 > x1) then
|
||||
--right
|
||||
if (y1 > y2) then
|
||||
--top
|
||||
selectionBoxUp:SetPoint("topleft", UIParent, "bottomleft", x1, y1)
|
||||
selectionBoxUp:SetPoint("topright", UIParent, "bottomleft", x2, y1)
|
||||
|
||||
selectionBoxLeft:SetPoint("topleft", UIParent, "bottomleft", x1, y1)
|
||||
selectionBoxLeft:SetPoint("bottomleft", UIParent, "bottomleft", x1, y2)
|
||||
|
||||
else
|
||||
--bottom
|
||||
end
|
||||
else
|
||||
--left
|
||||
if (y2 > y1) then
|
||||
--top
|
||||
else
|
||||
--bottom
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dragFrame:SetScript("OnMouseDown", function(self, MouseButton)
|
||||
if (MouseButton == "LeftButton") then
|
||||
self.ClickedAt = {GetCursorPosition()}
|
||||
dragFrame:SetScript("OnUpdate", dragFrame.OnTick)
|
||||
end
|
||||
end)
|
||||
|
||||
dragFrame:SetScript("OnMouseUp", function(self, MouseButton)
|
||||
if (MouseButton == "LeftButton") then
|
||||
self.ReleaseAt = {GetCursorPosition()}
|
||||
dragFrame:EnableMouse(false)
|
||||
dragFrame:Hide()
|
||||
dragFrame:SetScript("OnUpdate", nil)
|
||||
print(self.ClickedAt[1], self.ClickedAt[2], self.ReleaseAt[1], self.ReleaseAt[2])
|
||||
end
|
||||
end)
|
||||
|
||||
--accept
|
||||
editorWindow.accept = function(self, bottom, keepEditing)
|
||||
if (not keepEditing) then
|
||||
buttonsBackground:Hide()
|
||||
editorWindow:Hide()
|
||||
alphaFrame:Hide()
|
||||
ColorPickerFrame:Hide()
|
||||
end
|
||||
|
||||
local coords = {}
|
||||
local left, right, top, bottom = leftSlider.value/100, rightSlider.value/100, topSlider.value/100, bottomSlider.value/100
|
||||
|
||||
if (haveHFlip) then
|
||||
coords [1] = right
|
||||
coords [2] = left
|
||||
else
|
||||
coords [1] = left
|
||||
coords [2] = right
|
||||
end
|
||||
|
||||
if (haveVFlip) then
|
||||
coords [3] = bottom
|
||||
coords [4] = top
|
||||
else
|
||||
coords [3] = top
|
||||
coords [4] = bottom
|
||||
end
|
||||
|
||||
return editorWindow.callback_func(edit_texture.width, edit_texture.height, {edit_texture:GetVertexColor()}, edit_texture:GetAlpha(), coords, editorWindow.extra_param)
|
||||
end
|
||||
|
||||
local acceptButton = DF:NewButton(buttonsBackground, nil, "$parentAcceptButton", nil, 100, 20, editorWindow.accept, nil, nil, nil, "Done", 1)
|
||||
acceptButton:SetPoint("topright", buttonsBackground, "topright", -8, -200)
|
||||
acceptButton:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
function DF:RefreshImageEditor()
|
||||
if (edit_texture.maximize) then
|
||||
DetailsFrameworkImageEdit:SetSize(266, 226)
|
||||
else
|
||||
DetailsFrameworkImageEdit:SetSize(edit_texture.width, edit_texture.height)
|
||||
end
|
||||
|
||||
local left, right, top, bottom = unpack(texCoordinates)
|
||||
|
||||
if (left > right) then
|
||||
haveHFlip = true
|
||||
leftSlider:SetValue(right * 100)
|
||||
rightSlider:SetValue(left * 100)
|
||||
else
|
||||
haveHFlip = false
|
||||
leftSlider:SetValue(left * 100)
|
||||
rightSlider:SetValue(right * 100)
|
||||
end
|
||||
|
||||
if (top > bottom) then
|
||||
haveVFlip = true
|
||||
topSlider:SetValue(bottom * 100)
|
||||
bottomSlider:SetValue(top * 100)
|
||||
else
|
||||
haveVFlip = false
|
||||
topSlider:SetValue(top * 100)
|
||||
bottomSlider:SetValue(bottom * 100)
|
||||
end
|
||||
|
||||
if (editorWindow.callback_func) then
|
||||
editorWindow.accept(nil, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
editorWindow:Hide()
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function DF:ImageEditor(callback, texture, texcoord, colors, width, height, extraParam, alpha, maximize)
|
||||
if (not _G.DetailsFrameworkImageEdit) then
|
||||
CreateImageEditorFrame()
|
||||
end
|
||||
|
||||
local window = _G.DetailsFrameworkImageEditTable
|
||||
|
||||
texcoord = texcoord or {0, 1, 0, 1}
|
||||
texCoordinates = texcoord
|
||||
|
||||
colors = colors or {1, 1, 1, 1}
|
||||
|
||||
alpha = alpha or 1
|
||||
|
||||
_G.DetailsFrameworkImageEdit_EditTexture:SetTexture(texture)
|
||||
_G.DetailsFrameworkImageEdit_EditTexture.width = width
|
||||
_G.DetailsFrameworkImageEdit_EditTexture.height = height
|
||||
_G.DetailsFrameworkImageEdit_EditTexture.maximize = maximize
|
||||
|
||||
_G.DetailsFrameworkImageEdit_EditTexture:SetVertexColor(colors [1], colors [2], colors [3])
|
||||
_G.DetailsFrameworkImageEdit_EditTexture:SetAlpha(alpha)
|
||||
|
||||
DF.Schedules.NewTimer(0.2, DF.RefreshImageEditor)
|
||||
|
||||
window:Show()
|
||||
window.callback_func = callback
|
||||
window.extra_param = extraParam
|
||||
DetailsFrameworkImageEditButtonsBg:Show()
|
||||
DetailsFrameworkImageEditButtonsBg:SetBackdrop(nil)
|
||||
|
||||
table.wipe(window.hooks)
|
||||
end
|
||||
@@ -1,219 +0,0 @@
|
||||
|
||||
--stopped doing the duplicate savedTable
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
--create namespace
|
||||
DF.SavedVars = {}
|
||||
|
||||
function DF.SavedVars.CreateNewSavedTable(dbTable, savedTableName)
|
||||
local defaultVars = dbTable.defaultSavedVars
|
||||
local newSavedTable = DF.table.deploy({}, defaultVars)
|
||||
|
||||
dbTable.profiles[savedTableName] = newSavedTable
|
||||
return newSavedTable
|
||||
end
|
||||
|
||||
function DF.SavedVars.GetOrCreateAddonSavedTablesPlayerList(addonFrame)
|
||||
local addonGlobalSavedTable = _G[addonFrame.__savedVarsName]
|
||||
|
||||
--player list
|
||||
local playerList = addonGlobalSavedTable.__savedVarsByGUID
|
||||
if (not playerList) then
|
||||
addonGlobalSavedTable.__savedVarsByGUID = {}
|
||||
end
|
||||
|
||||
--saved variables table
|
||||
if (not addonGlobalSavedTable.__savedVars) then
|
||||
addonGlobalSavedTable.__savedVars = {}
|
||||
end
|
||||
|
||||
return addonGlobalSavedTable.__savedVarsByGUID
|
||||
end
|
||||
|
||||
--addon statup
|
||||
function DF.SavedVars.LoadSavedVarsForPlayer(addonFrame)
|
||||
local playerSerial = UnitGUID("player")
|
||||
|
||||
--savedTableObject is equivalent of "addon.db"
|
||||
local dbTable = DF.SavedVars.CreateSavedVarsTable(addonFrame, addonFrame.__savedVarsDefaultTemplate)
|
||||
addonFrame.__savedVarsDefaultTemplate = nil
|
||||
addonFrame.db = dbTable
|
||||
|
||||
--load players list
|
||||
local savedVarsName = DF.SavedVars.GetOrCreateAddonSavedTablesPlayerList(addonFrame)
|
||||
|
||||
local playerSavedTableName = savedVarsName[playerSerial]
|
||||
if (not playerSavedTableName) then
|
||||
savedVarsName[playerSerial] = "Default"
|
||||
playerSavedTableName = savedVarsName[playerSerial]
|
||||
end
|
||||
|
||||
local savedTable = addonFrame.db:GetSavedTable(playerSavedTableName)
|
||||
if (not savedTable) then
|
||||
--create a new saved table for this character
|
||||
savedTable = addonFrame.db:CreateNewSavedTable(playerSavedTableName)
|
||||
end
|
||||
|
||||
DF.SavedVars.SetSavedTable(dbTable, playerSavedTableName, true, true)
|
||||
return savedTable
|
||||
end
|
||||
|
||||
function DF.SavedVars.TableCleanUpRecursive(t, default)
|
||||
for key, value in pairs(t) do
|
||||
if (type(value) == "table") then
|
||||
DF.SavedVars.TableCleanUpRecursive(value, default[key])
|
||||
else
|
||||
if (value == default[key]) then
|
||||
t[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DF.SavedVars.CloseSavedTable(dbTable)
|
||||
local currentSavedTable = dbTable:GetSavedTable(dbTable:GetCurrentSavedTableName())
|
||||
|
||||
local default = dbTable.defaultSavedVars
|
||||
if (type(currentSavedTable) == "table") then
|
||||
DF.SavedVars.TableCleanUpRecursive(currentSavedTable, default)
|
||||
|
||||
--save
|
||||
local addonGlobalSavedTable = _G[dbTable.addonFrame.__savedVarsName]
|
||||
addonGlobalSavedTable.__savedVars[dbTable:GetCurrentSavedTableName()] = currentSavedTable
|
||||
end
|
||||
end
|
||||
|
||||
--base functions
|
||||
function DF.SavedVars.SetSavedTable(dbTable, savedTableName, createIfNonExistant, isFromInit)
|
||||
local savedTableToBeApplied = dbTable:GetSavedTable(savedTableName)
|
||||
|
||||
if (savedTableToBeApplied) then
|
||||
if (not isFromInit) then
|
||||
--callback unload profile table
|
||||
local currentSavedTable = dbTable:GetSavedTable(dbTable:GetCurrentSavedTableName())
|
||||
dbTable:TriggerCallback("OnProfileUnload", currentSavedTable)
|
||||
DF.SavedVars.CloseSavedTable(dbTable, currentSavedTable)
|
||||
end
|
||||
|
||||
dbTable.profile = savedTableToBeApplied
|
||||
dbTable.currentSavedTableName = savedTableName
|
||||
|
||||
dbTable:TriggerCallback("OnProfileLoad", savedTableToBeApplied)
|
||||
|
||||
else
|
||||
if (createIfNonExistant) then
|
||||
local newSavedTable = dbTable:CreateNewSavedTable(savedTableName)
|
||||
|
||||
--callback unload profile table
|
||||
local currentSavedTable = dbTable:GetSavedTable(dbTable:GetCurrentSavedTableName())
|
||||
dbTable:TriggerCallback("OnProfileUnload", currentSavedTable)
|
||||
DF.SavedVars.CloseSavedTable(dbTable, currentSavedTable)
|
||||
|
||||
dbTable.profile = newSavedTable
|
||||
dbTable.currentSavedTableName = savedTableName
|
||||
dbTable:TriggerCallback("OnProfileLoad", newSavedTable)
|
||||
else
|
||||
DF:Msg("profile does not exists", savedTableName)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DF.SavedVars.GetSavedTables(dbTable)
|
||||
return dbTable.profiles
|
||||
end
|
||||
|
||||
function DF.SavedVars.GetSavedTable(dbTable, savedTableName)
|
||||
local profiles = dbTable:GetSavedTables()
|
||||
return profiles[savedTableName]
|
||||
end
|
||||
|
||||
function DF.SavedVars.GetCurrentSavedTableName(dbTable)
|
||||
return dbTable.currentSavedTableName
|
||||
end
|
||||
|
||||
--duplicate savedTable
|
||||
function DF.SavedVars.DuplicateSavedTable(dbTable, savedTableName)
|
||||
local originalSavedTable = dbTable:GetSavedTable(savedTableName)
|
||||
if (originalSavedTable) then
|
||||
local newSavedTable = DF.table.copy({}, originalSavedTable)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--callbacks
|
||||
function DF.SavedVars.TriggerCallback(dbTable, callbackName, savedTable)
|
||||
local registeredCallbacksTable = dbTable.registeredCallbacks[callbackName]
|
||||
for i = 1, #registeredCallbacksTable do
|
||||
local callback = registeredCallbacksTable[i]
|
||||
DF:CoreDispatch(dbTable.addonFrame.__name, callback.func, savedTable, unpack(callback.payload))
|
||||
end
|
||||
end
|
||||
|
||||
function DF.SavedVars.RegisterCallback(dbTable, callbackName, func, ...)
|
||||
local registeredCallbacksTable = dbTable.registeredCallbacks[callbackName]
|
||||
if (registeredCallbacksTable) then
|
||||
--check for duplicates
|
||||
for i = 1, #registeredCallbacksTable do
|
||||
if (registeredCallbacksTable[i].func == func) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--register
|
||||
registeredCallbacksTable[#registeredCallbacksTable+1] = {func = func, payload = {...}}
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function DF.SavedVars.UnregisterCallback(dbTable, callbackName, func)
|
||||
local registeredCallbacksTable = dbTable.registeredCallbacks[callbackName]
|
||||
if (registeredCallbacksTable) then
|
||||
for i = 1, #registeredCallbacksTable do
|
||||
if (registeredCallbacksTable[i].func == func) then
|
||||
tremove(registeredCallbacksTable, i)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DF.SavedVars.CreateSavedVarsTable(addonFrame, templateTable)
|
||||
local dbTable = {
|
||||
profiles = {},
|
||||
defaultSavedVars = templateTable,
|
||||
currentSavedTableName = "",
|
||||
addonFrame = addonFrame,
|
||||
|
||||
--methods
|
||||
GetSavedTable = DF.SavedVars.GetSavedTable,
|
||||
SetSavedTable = DF.SavedVars.SetSavedTable,
|
||||
GetSavedTables = DF.SavedVars.GetSavedTables,
|
||||
GetCurrentSavedTableName = DF.SavedVars.GetCurrentSavedTableName,
|
||||
CreateNewSavedTable = DF.SavedVars.CreateNewSavedTable,
|
||||
TriggerCallback = DF.SavedVars.TriggerCallback,
|
||||
|
||||
--back compatibility with ace3DB
|
||||
GetCurrentProfile = DF.SavedVars.GetCurrentSavedTableName,
|
||||
GetProfile = DF.SavedVars.GetSavedTable,
|
||||
GetProfiles = DF.SavedVars.GetSavedTables,
|
||||
SetProfile = DF.SavedVars.SetSavedTable,
|
||||
RegisterCallback = DF.SavedVars.RegisterCallback,
|
||||
|
||||
registeredCallbacks = {
|
||||
["OnProfileLoad"] = {},
|
||||
["OnProfileUnload"] = {},
|
||||
["OnProfileCopied"] = {},
|
||||
["OnProfileReset"] = {},
|
||||
["OnDatabaseLoad"] = {},
|
||||
["OnDatabaseShutdown"] = {},
|
||||
},
|
||||
}
|
||||
|
||||
return dbTable
|
||||
end
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local C_Timer = _G.C_Timer
|
||||
local unpack = table.unpack or _G.unpack
|
||||
|
||||
--make a namespace for schedules
|
||||
DF.Schedules = DF.Schedules or {}
|
||||
|
||||
--run a scheduled function with its payload
|
||||
local triggerScheduledTick = function(tickerObject)
|
||||
local payload = tickerObject.payload
|
||||
local callback = tickerObject.callback
|
||||
|
||||
local result, errortext = pcall(callback, unpack(payload))
|
||||
if (not result) then
|
||||
DF:Msg("error on scheduler: ", tickerObject.path, tickerObject.name, errortext)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--schedule to repeat a task with an interval of @time
|
||||
function DF.Schedules.NewTicker(time, callback, ...)
|
||||
local payload = {...}
|
||||
local newTicker = C_Timer.NewTicker(time, triggerScheduledTick)
|
||||
newTicker.payload = payload
|
||||
newTicker.callback = callback
|
||||
newTicker.expireAt = GetTime() + time
|
||||
|
||||
--debug
|
||||
newTicker.path = debugstack()
|
||||
--
|
||||
return newTicker
|
||||
end
|
||||
|
||||
--schedule a task with an interval of @time
|
||||
function DF.Schedules.NewTimer(time, callback, ...)
|
||||
local payload = {...}
|
||||
local newTimer = C_Timer.NewTimer(time, triggerScheduledTick)
|
||||
newTimer.payload = payload
|
||||
newTimer.callback = callback
|
||||
newTimer.expireAt = GetTime() + time
|
||||
|
||||
--debug
|
||||
newTimer.path = debugstack()
|
||||
--
|
||||
|
||||
return newTimer
|
||||
end
|
||||
|
||||
--cancel an ongoing ticker
|
||||
function DF.Schedules.Cancel(tickerObject)
|
||||
--ignore if there's no ticker object
|
||||
if (tickerObject) then
|
||||
return tickerObject:Cancel()
|
||||
end
|
||||
end
|
||||
|
||||
--schedule a task with an interval of @time without payload
|
||||
function DF.Schedules.After(time, callback)
|
||||
C_Timer.After(time, callback)
|
||||
end
|
||||
|
||||
function DF.Schedules.SetName(object, name)
|
||||
object.name = name
|
||||
end
|
||||
|
||||
function DF.Schedules.RunNextTick(callback)
|
||||
return DF.Schedules.After(0, callback)
|
||||
end
|
||||
@@ -1,132 +0,0 @@
|
||||
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local geterrorhandler = geterrorhandler
|
||||
local wipe = wipe
|
||||
|
||||
local parseCodeForNamedLocalFunctions = function(codeBlock, startIndex, listOfFunctionsFound)
|
||||
local nestedLevel = 0
|
||||
local endIndex = startIndex
|
||||
local currentQuote = ""
|
||||
---@type number for the 'function' keyword, need to ignore the one that started the 'local function' capture
|
||||
local ignoreFunctionIndex = startIndex + 6
|
||||
|
||||
---@type boolean
|
||||
local bFoundEnd = false
|
||||
---@type boolean
|
||||
local bIsInString = false
|
||||
---@type boolean
|
||||
local bIsInComment = false
|
||||
|
||||
while (endIndex <= #codeBlock) do
|
||||
local char = string.sub(codeBlock, endIndex, endIndex)
|
||||
|
||||
--check if the character is inside a comment
|
||||
if (char == "-") then
|
||||
local nextChar = string.sub(codeBlock, endIndex + 1, endIndex + 1)
|
||||
if nextChar == "-" then
|
||||
bIsInComment = true
|
||||
end
|
||||
|
||||
elseif (char == "\n") then
|
||||
bIsInComment = false
|
||||
end
|
||||
|
||||
if (not bIsInComment) then
|
||||
--check if it is inside a string
|
||||
if (char == "'" or char == '"') then
|
||||
if (not bIsInString) then
|
||||
bIsInString = true
|
||||
currentQuote = char
|
||||
|
||||
elseif (bIsInString and currentQuote == char) then
|
||||
bIsInString = false
|
||||
currentQuote = ""
|
||||
end
|
||||
end
|
||||
|
||||
if (not bIsInString) then
|
||||
--check if the word starts with "i", "f", "d" or "e"
|
||||
if (char == "i") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 1)
|
||||
if (nextChars == "if") then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
elseif (char == "f") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 7)
|
||||
--also check if the index isn't the one that started the 'local function' capture
|
||||
if (nextChars == "function" and endIndex ~= ignoreFunctionIndex) then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
--for 'do' keyword, used by for and while and also by the 'do' keyword itself creating a block
|
||||
elseif (char == "d") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 1)
|
||||
if (nextChars == "do") then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
elseif (char == "e") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 2)
|
||||
if (nextChars == "end") then
|
||||
if (nestedLevel > 0) then
|
||||
--reduce the nested level by 1
|
||||
nestedLevel = nestedLevel - 1
|
||||
else
|
||||
--if the nested level is zero then the end of the function got found
|
||||
bFoundEnd = true
|
||||
endIndex = endIndex + 2 --adjust endIndex to include the 'end' keyword
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endIndex = endIndex + 1
|
||||
end
|
||||
|
||||
if (bFoundEnd) then
|
||||
---@type string get the function body
|
||||
local functionBody = string.sub(codeBlock, startIndex, endIndex)
|
||||
table.insert(listOfFunctionsFound, functionBody)
|
||||
return endIndex
|
||||
end
|
||||
end
|
||||
|
||||
---search a code block for named local functions and bring them to the top of the code block
|
||||
---this is useful for when you want to call a function before it's defined
|
||||
---same thing as been implemented in Lua 5.2 but not in WoW Lua
|
||||
---@param codeBlock string
|
||||
function detailsFramework:BringNamedLocalFunctionToTop(codeBlock)
|
||||
---@type string[]
|
||||
local listOfFunctionsFound = {}
|
||||
---@type number|nil
|
||||
local startIndex = string.find(codeBlock, "local function")
|
||||
|
||||
while startIndex do
|
||||
startIndex = parseCodeForNamedLocalFunctions(codeBlock, startIndex, listOfFunctionsFound)
|
||||
if (not startIndex) then
|
||||
break
|
||||
end
|
||||
startIndex = string.find(codeBlock, "local function", startIndex + 1)
|
||||
end
|
||||
|
||||
for i = #listOfFunctionsFound, 1, -1 do
|
||||
local thisMatch = listOfFunctionsFound[i]
|
||||
local blockStartIndex = thisMatch[2]
|
||||
local blockEndIndex = thisMatch[3]
|
||||
codeBlock = codeBlock:sub(1, blockStartIndex - 1) .. codeBlock:sub(blockEndIndex + 1)
|
||||
end
|
||||
|
||||
for i = #listOfFunctionsFound, 1, -1 do
|
||||
codeBlock = listOfFunctionsFound[i][1] .. "\n\n" .. codeBlock
|
||||
end
|
||||
end
|
||||
@@ -1,233 +0,0 @@
|
||||
|
||||
--note: this scroll bar is using legacy code and shouldn't be used on creating new stuff
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
function DF:CreateScrollBar(master, scrollContainer, x, y)
|
||||
return DF:NewScrollBar(master, scrollContainer, x, y)
|
||||
end
|
||||
|
||||
function DF:NewScrollBar(parent, scrollContainer, x, y)
|
||||
local newSlider = CreateFrame("Slider", nil, parent, "BackdropTemplate")
|
||||
newSlider.scrollMax = 560
|
||||
|
||||
newSlider:SetPoint("TOPLEFT", parent, "TOPRIGHT", x, y)
|
||||
newSlider.ativo = true
|
||||
|
||||
newSlider.bg = newSlider:CreateTexture(nil, "BACKGROUND")
|
||||
newSlider.bg:SetAllPoints(true)
|
||||
newSlider.bg:SetTexture(0, 0, 0, 0)
|
||||
|
||||
newSlider.thumb = newSlider:CreateTexture(nil, "OVERLAY")
|
||||
newSlider.thumb:SetTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
|
||||
newSlider.thumb:SetSize(29, 30)
|
||||
newSlider:SetThumbTexture(newSlider.thumb)
|
||||
newSlider:SetOrientation("VERTICAL")
|
||||
newSlider:SetSize(16, 100)
|
||||
newSlider:SetMinMaxValues(0, newSlider.scrollMax)
|
||||
newSlider:SetValue(0)
|
||||
newSlider.ultimo = 0
|
||||
|
||||
local upButton = CreateFrame("Button", nil, parent,"BackdropTemplate")
|
||||
|
||||
upButton:SetPoint("BOTTOM", newSlider, "TOP", 0, -12)
|
||||
upButton.x = 0
|
||||
upButton.y = -12
|
||||
|
||||
upButton:SetWidth(29)
|
||||
upButton:SetHeight(32)
|
||||
upButton:SetNormalTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollUpButton-Up")
|
||||
upButton:SetPushedTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollUpButton-Down")
|
||||
upButton:SetDisabledTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollUpButton-Disabled")
|
||||
upButton:Show()
|
||||
upButton:Disable()
|
||||
|
||||
local downDutton = CreateFrame("Button", nil, parent,"BackdropTemplate")
|
||||
downDutton:SetPoint("TOP", newSlider, "BOTTOM", 0, 12)
|
||||
downDutton.x = 0
|
||||
downDutton.y = 12
|
||||
|
||||
downDutton:SetWidth(29)
|
||||
downDutton:SetHeight(32)
|
||||
downDutton:SetNormalTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollDownButton-Up")
|
||||
downDutton:SetPushedTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollDownButton-Down")
|
||||
downDutton:SetDisabledTexture("Interface\\BUTTONS\\UI-ScrollBar-ScrollDownButton-Disabled")
|
||||
downDutton:Show()
|
||||
downDutton:Disable()
|
||||
|
||||
parent.baixo = downDutton
|
||||
parent.cima = upButton
|
||||
parent.slider = newSlider
|
||||
|
||||
downDutton:SetScript("OnMouseDown", function(self)
|
||||
if (not newSlider:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = newSlider:GetValue()
|
||||
local minValue, maxValue = newSlider:GetMinMaxValues()
|
||||
if (current + 5 < maxValue) then
|
||||
newSlider:SetValue(current + 5)
|
||||
else
|
||||
newSlider:SetValue(maxValue)
|
||||
end
|
||||
self.precionado = true
|
||||
self.last_up = -0.3
|
||||
self:SetScript("OnUpdate", function(self, elapsed)
|
||||
self.last_up = self.last_up + elapsed
|
||||
if (self.last_up > 0.03) then
|
||||
self.last_up = 0
|
||||
local current = newSlider:GetValue()
|
||||
local minValue, maxValue = newSlider:GetMinMaxValues()
|
||||
if (current + 2 < maxValue) then
|
||||
newSlider:SetValue(current + 2)
|
||||
else
|
||||
newSlider:SetValue(maxValue)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
downDutton:SetScript("OnMouseUp", function(self)
|
||||
self.precionado = false
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
|
||||
upButton:SetScript("OnMouseDown", function(self)
|
||||
if (not newSlider:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = newSlider:GetValue()
|
||||
if (current - 5 > 0) then
|
||||
newSlider:SetValue(current - 5)
|
||||
else
|
||||
newSlider:SetValue(0)
|
||||
end
|
||||
|
||||
self.precionado = true
|
||||
self.last_up = -0.3
|
||||
self:SetScript("OnUpdate", function(self, elapsed)
|
||||
self.last_up = self.last_up + elapsed
|
||||
if (self.last_up > 0.03) then
|
||||
self.last_up = 0
|
||||
local current = newSlider:GetValue()
|
||||
if (current - 2 > 0) then
|
||||
newSlider:SetValue(current - 2)
|
||||
else
|
||||
newSlider:SetValue(0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
upButton:SetScript("OnMouseUp", function(self)
|
||||
self.precionado = false
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
|
||||
upButton:SetScript("OnEnable", function(self)
|
||||
local current = newSlider:GetValue()
|
||||
if (current == 0) then
|
||||
upButton:Disable()
|
||||
end
|
||||
end)
|
||||
|
||||
newSlider:SetScript("OnValueChanged", function(self)
|
||||
local current = self:GetValue()
|
||||
parent:SetVerticalScroll(current)
|
||||
|
||||
local minValue, maxValue = newSlider:GetMinMaxValues()
|
||||
|
||||
if (current == minValue) then
|
||||
upButton:Disable()
|
||||
elseif (not upButton:IsEnabled()) then
|
||||
upButton:Enable()
|
||||
end
|
||||
|
||||
if (current == maxValue) then
|
||||
downDutton:Disable()
|
||||
elseif (not downDutton:IsEnabled()) then
|
||||
downDutton:Enable()
|
||||
end
|
||||
end)
|
||||
|
||||
newSlider:SetScript("OnShow", function(self)
|
||||
upButton:Show()
|
||||
downDutton:Show()
|
||||
end)
|
||||
|
||||
newSlider:SetScript("OnDisable", function(self)
|
||||
upButton:Disable()
|
||||
downDutton:Disable()
|
||||
end)
|
||||
|
||||
newSlider:SetScript("OnEnable", function(self)
|
||||
upButton:Enable()
|
||||
downDutton:Enable()
|
||||
end)
|
||||
|
||||
parent:SetScript("OnMouseWheel", function(self, delta)
|
||||
if (not newSlider:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = newSlider:GetValue()
|
||||
if (delta < 0) then
|
||||
local minValue, maxValue = newSlider:GetMinMaxValues()
|
||||
if (current + (parent.wheel_jump or 20) < maxValue) then
|
||||
newSlider:SetValue(current + (parent.wheel_jump or 20))
|
||||
else
|
||||
newSlider:SetValue(maxValue)
|
||||
end
|
||||
elseif (delta > 0) then
|
||||
if (current + (parent.wheel_jump or 20) > 0) then
|
||||
newSlider:SetValue(current - (parent.wheel_jump or 20))
|
||||
else
|
||||
newSlider:SetValue(0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function newSlider:Altura(height)
|
||||
self:SetHeight(height)
|
||||
end
|
||||
|
||||
function newSlider:Update(desativar)
|
||||
if (desativar) then
|
||||
newSlider:Disable()
|
||||
newSlider:SetValue(0)
|
||||
newSlider.ativo = false
|
||||
parent:EnableMouseWheel(false)
|
||||
return
|
||||
end
|
||||
|
||||
self.scrollMax = scrollContainer:GetHeight() - parent:GetHeight()
|
||||
if (self.scrollMax > 0) then
|
||||
newSlider:SetMinMaxValues(0, self.scrollMax)
|
||||
if (not newSlider.ativo) then
|
||||
newSlider:Enable()
|
||||
newSlider.ativo = true
|
||||
parent:EnableMouseWheel(true)
|
||||
end
|
||||
else
|
||||
newSlider:Disable()
|
||||
newSlider:SetValue(0)
|
||||
newSlider.ativo = false
|
||||
parent:EnableMouseWheel(false)
|
||||
end
|
||||
end
|
||||
|
||||
function newSlider:cimaPoint(x, y)
|
||||
upButton:SetPoint("BOTTOM", newSlider, "TOP", x, y - 12)
|
||||
end
|
||||
|
||||
function newSlider:baixoPoint(x, y)
|
||||
downDutton:SetPoint("TOP", newSlider, "BOTTOM", x, y + 12)
|
||||
end
|
||||
|
||||
return newSlider
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,810 +0,0 @@
|
||||
|
||||
local DF = _G ["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local rawset = rawset --lua local
|
||||
local rawget = rawget --lua local
|
||||
local setmetatable = setmetatable --lua local
|
||||
local _unpack = unpack --lua local
|
||||
local type = type --lua local
|
||||
local _math_floor = math.floor --lua local
|
||||
|
||||
local maxStatusBarValue = 100000000
|
||||
|
||||
local cleanfunction = function() end
|
||||
local APISplitBarFunctions
|
||||
|
||||
do
|
||||
local metaPrototype = {
|
||||
WidgetType = "split_bar",
|
||||
dversion = DF.dversion,
|
||||
}
|
||||
|
||||
--check if there's a metaPrototype already existing
|
||||
if (_G[DF.GlobalWidgetControlNames["split_bar"]]) then
|
||||
--get the already existing metaPrototype
|
||||
local oldMetaPrototype = _G[DF.GlobalWidgetControlNames["split_bar"]]
|
||||
--check if is older
|
||||
if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < DF.dversion) ) then
|
||||
--the version is older them the currently loading one
|
||||
--copy the new values into the old metatable
|
||||
for funcName, _ in pairs(metaPrototype) do
|
||||
oldMetaPrototype[funcName] = metaPrototype[funcName]
|
||||
end
|
||||
end
|
||||
else
|
||||
--first time loading the framework
|
||||
_G[DF.GlobalWidgetControlNames["split_bar"]] = metaPrototype
|
||||
end
|
||||
end
|
||||
|
||||
local SplitBarMetaFunctions = _G[DF.GlobalWidgetControlNames["split_bar"]]
|
||||
DF:Mixin(SplitBarMetaFunctions, DF.ScriptHookMixin)
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--metatables
|
||||
|
||||
SplitBarMetaFunctions.__call = function(_table, value)
|
||||
if (not value) then
|
||||
return _table.statusbar:GetValue()
|
||||
else
|
||||
_table.spark:SetPoint("left", _table.statusbar, "left", value * (_table.statusbar:GetWidth()/100) - 18, 0)
|
||||
return _table.statusbar:SetValue(value)
|
||||
end
|
||||
end
|
||||
|
||||
SplitBarMetaFunctions.__add = function(v1, v2)
|
||||
if (type(v1) == "table") then
|
||||
local v = v1.statusbar:GetValue()
|
||||
v = v + v2
|
||||
v1.spark:SetPoint("left", v1.statusbar, "left", value * (v1.statusbar:GetWidth()/100) - 18, 0)
|
||||
v1.statusbar:SetValue(v)
|
||||
else
|
||||
local v = v2.statusbar:GetValue()
|
||||
v = v + v1
|
||||
v2.spark:SetPoint("left", v2.statusbar, "left", value * (v2.statusbar:GetWidth()/100) - 18, 0)
|
||||
v2.statusbar:SetValue(v)
|
||||
end
|
||||
end
|
||||
|
||||
SplitBarMetaFunctions.__sub = function(v1, v2)
|
||||
if (type(v1) == "table") then
|
||||
local v = v1.statusbar:GetValue()
|
||||
v = v - v2
|
||||
v1.spark:SetPoint("left", v1.statusbar, "left", value * (v1.statusbar:GetWidth()/100) - 18, 0)
|
||||
v1.statusbar:SetValue(v)
|
||||
else
|
||||
local v = v2.statusbar:GetValue()
|
||||
v = v - v1
|
||||
v2.spark:SetPoint("left", v2.statusbar, "left", value * (v2.statusbar:GetWidth()/100) - 18, 0)
|
||||
v2.statusbar:SetValue(v)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--members
|
||||
|
||||
--tooltip
|
||||
local function gmember_tooltip (_object)
|
||||
return _object:GetTooltip()
|
||||
end
|
||||
--shown
|
||||
local gmember_shown = function(_object)
|
||||
return _object.statusbar:IsShown()
|
||||
end
|
||||
--frame width
|
||||
local gmember_width = function(_object)
|
||||
return _object.statusbar:GetWidth()
|
||||
end
|
||||
--frame height
|
||||
local gmember_height = function(_object)
|
||||
return _object.statusbar:GetHeight()
|
||||
end
|
||||
--value
|
||||
local gmember_value = function(_object)
|
||||
return _object.statusbar:GetValue()
|
||||
end
|
||||
--right text
|
||||
local gmember_rtext = function(_object)
|
||||
return _object.textright:GetText()
|
||||
end
|
||||
--left text
|
||||
local gmember_ltext = function(_object)
|
||||
return _object.textleft:GetText()
|
||||
end
|
||||
--right color
|
||||
local gmember_rcolor = function(_object)
|
||||
return _object.rightTexture.original_colors
|
||||
end
|
||||
--left color
|
||||
local gmember_lcolor = function(_object)
|
||||
return _object.texture.original_colors
|
||||
end
|
||||
--right icon
|
||||
local gmember_ricon = function(_object)
|
||||
return _object.iconright:GetTexture()
|
||||
end
|
||||
--left icon
|
||||
local gmember_licon = function(_object)
|
||||
return _object.iconleft:GetTexture()
|
||||
end
|
||||
--texture
|
||||
local gmember_texture = function(_object)
|
||||
return _object.texture:GetTexture()
|
||||
end
|
||||
--font size
|
||||
local gmember_textsize = function(_object)
|
||||
local _, fontsize = _object.textleft:GetFont()
|
||||
return fontsize
|
||||
end
|
||||
--font face
|
||||
local gmember_textfont = function(_object)
|
||||
local fontface = _object.textleft:GetFont()
|
||||
return fontface
|
||||
end
|
||||
--font color
|
||||
local gmember_textcolor = function(_object)
|
||||
return _object.textleft:GetTextColor()
|
||||
end
|
||||
|
||||
SplitBarMetaFunctions.GetMembers = SplitBarMetaFunctions.GetMembers or {}
|
||||
SplitBarMetaFunctions.GetMembers ["tooltip"] = gmember_tooltip
|
||||
SplitBarMetaFunctions.GetMembers ["shown"] = gmember_shown
|
||||
SplitBarMetaFunctions.GetMembers ["width"] = gmember_width
|
||||
SplitBarMetaFunctions.GetMembers ["height"] = gmember_height
|
||||
SplitBarMetaFunctions.GetMembers ["value"] = gmember_value
|
||||
SplitBarMetaFunctions.GetMembers ["righttext"] = gmember_rtext
|
||||
SplitBarMetaFunctions.GetMembers ["lefttext"] = gmember_ltext
|
||||
SplitBarMetaFunctions.GetMembers ["rightcolor"] = gmember_rcolor
|
||||
SplitBarMetaFunctions.GetMembers ["leftcolor"] = gmember_lcolor
|
||||
SplitBarMetaFunctions.GetMembers ["righticon"] = gmember_ricon
|
||||
SplitBarMetaFunctions.GetMembers ["lefticon"] = gmember_licon
|
||||
SplitBarMetaFunctions.GetMembers ["texture"] = gmember_texture
|
||||
SplitBarMetaFunctions.GetMembers ["fontsize"] = gmember_textsize
|
||||
SplitBarMetaFunctions.GetMembers ["fontface"] = gmember_textfont
|
||||
SplitBarMetaFunctions.GetMembers ["fontcolor"] = gmember_textcolor
|
||||
SplitBarMetaFunctions.GetMembers ["textsize"] = gmember_textsize --alias
|
||||
SplitBarMetaFunctions.GetMembers ["textfont"] = gmember_textfont --alias
|
||||
SplitBarMetaFunctions.GetMembers ["textcolor"] = gmember_textcolor --alias
|
||||
|
||||
SplitBarMetaFunctions.__index = function(_table, _member_requested)
|
||||
|
||||
local func = SplitBarMetaFunctions.GetMembers [_member_requested]
|
||||
if (func) then
|
||||
return func (_table, _member_requested)
|
||||
end
|
||||
|
||||
local fromMe = rawget (_table, _member_requested)
|
||||
if (fromMe) then
|
||||
return fromMe
|
||||
end
|
||||
|
||||
return SplitBarMetaFunctions [_member_requested]
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--tooltip
|
||||
local smember_tooltip = function(_object, _value)
|
||||
return _object:SetTooltip (_value)
|
||||
end
|
||||
--show
|
||||
local smember_shown = function(_object, _value)
|
||||
if (_value) then
|
||||
return _object:Show()
|
||||
else
|
||||
return _object:Hide()
|
||||
end
|
||||
end
|
||||
--hide
|
||||
local smember_hide = function(_object, _value)
|
||||
if (_value) then
|
||||
return _object:Hide()
|
||||
else
|
||||
return _object:Show()
|
||||
end
|
||||
end
|
||||
--width
|
||||
local smember_width = function(_object, _value)
|
||||
return _object.statusbar:SetWidth(_value)
|
||||
end
|
||||
--height
|
||||
local smember_height = function(_object, _value)
|
||||
return _object.statusbar:SetHeight(_value)
|
||||
end
|
||||
--statusbar value
|
||||
local smember_value = function(_object, _value)
|
||||
_object.statusbar:SetValue(_value)
|
||||
return _object.spark:SetPoint("left", _object.statusbar, "left", _value * (_object.statusbar:GetWidth()/100) - 18, 0)
|
||||
end
|
||||
--right text
|
||||
local smember_rtext = function(_object, _value)
|
||||
return _object.textright:SetText(_value)
|
||||
end
|
||||
--left text
|
||||
local smember_ltext = function(_object, _value)
|
||||
return _object.textleft:SetText(_value)
|
||||
end
|
||||
--right color
|
||||
local smember_rcolor = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
_object.rightTexture.original_colors = {_value1, _value2, _value3, _value4}
|
||||
return _object.rightTexture:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
--left color
|
||||
local smember_lcolor = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
|
||||
_object.statusbar:SetStatusBarColor(_value1, _value2, _value3, _value4)
|
||||
_object.texture.original_colors = {_value1, _value2, _value3, _value4}
|
||||
return _object.texture:SetVertexColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
--right icon
|
||||
local smember_ricon = function(_object, _value)
|
||||
if (type(_value) == "table") then
|
||||
local _value1, _value2 = _unpack(_value)
|
||||
_object.iconright:SetTexture(_value1)
|
||||
if (_value2) then
|
||||
_object.iconright:SetTexCoord(_unpack(_value2))
|
||||
end
|
||||
else
|
||||
_object.iconright:SetTexture(_value)
|
||||
end
|
||||
return
|
||||
end
|
||||
--left icon
|
||||
local smember_licon = function(_object, _value)
|
||||
if (type(_value) == "table") then
|
||||
local _value1, _value2 = _unpack(_value)
|
||||
_object.iconleft:SetTexture(_value1)
|
||||
if (_value2) then
|
||||
_object.iconleft:SetTexCoord(_unpack(_value2))
|
||||
end
|
||||
else
|
||||
_object.iconleft:SetTexture(_value)
|
||||
end
|
||||
return
|
||||
end
|
||||
--texture
|
||||
local smember_texture = function(_object, _value)
|
||||
if (type(_value) == "table") then
|
||||
local _value1, _value2 = _unpack(_value)
|
||||
_object.texture:SetTexture(_value1)
|
||||
_object.rightTexture:SetTexture(_value1)
|
||||
if (_value2) then
|
||||
_object.texture:SetTexCoord(_unpack(_value2))
|
||||
_object.rightTexture:SetTexCoord(_unpack(_value2))
|
||||
end
|
||||
else
|
||||
_object.texture:SetTexture(_value)
|
||||
_object.rightTexture:SetTexture(_value)
|
||||
end
|
||||
return
|
||||
end
|
||||
--font face
|
||||
local smember_textfont = function(_object, _value)
|
||||
DF:SetFontFace (_object.textleft, _value)
|
||||
return DF:SetFontFace (_object.textright, _value)
|
||||
end
|
||||
--font size
|
||||
local smember_textsize = function(_object, _value)
|
||||
DF:SetFontSize(_object.textleft, _value)
|
||||
return DF:SetFontSize(_object.textright, _value)
|
||||
end
|
||||
--font color
|
||||
local smember_textcolor = function(_object, _value)
|
||||
local _value1, _value2, _value3, _value4 = DF:ParseColors(_value)
|
||||
_object.textleft:SetTextColor(_value1, _value2, _value3, _value4)
|
||||
return _object.textright:SetTextColor(_value1, _value2, _value3, _value4)
|
||||
end
|
||||
|
||||
SplitBarMetaFunctions.SetMembers = SplitBarMetaFunctions.SetMembers or {}
|
||||
SplitBarMetaFunctions.SetMembers ["tooltip"] = smember_tooltip
|
||||
SplitBarMetaFunctions.SetMembers ["shown"] = smember_shown
|
||||
SplitBarMetaFunctions.SetMembers ["width"] = smember_width
|
||||
SplitBarMetaFunctions.SetMembers ["height"] = smember_height
|
||||
SplitBarMetaFunctions.SetMembers ["value"] = smember_value
|
||||
SplitBarMetaFunctions.SetMembers ["righttext"] = smember_rtext
|
||||
SplitBarMetaFunctions.SetMembers ["lefttext"] = smember_ltext
|
||||
SplitBarMetaFunctions.SetMembers ["rightcolor"] = smember_rcolor
|
||||
SplitBarMetaFunctions.SetMembers ["leftcolor"] = smember_lcolor
|
||||
SplitBarMetaFunctions.SetMembers ["righticon"] = smember_ricon
|
||||
SplitBarMetaFunctions.SetMembers ["lefticon"] = smember_licon
|
||||
SplitBarMetaFunctions.SetMembers ["texture"] = smember_texture
|
||||
SplitBarMetaFunctions.SetMembers ["fontsize"] = smember_textsize
|
||||
SplitBarMetaFunctions.SetMembers ["fontface"] = smember_textfont
|
||||
SplitBarMetaFunctions.SetMembers ["fontcolor"] = smember_textcolor
|
||||
SplitBarMetaFunctions.SetMembers ["textsize"] = smember_textsize --alias
|
||||
SplitBarMetaFunctions.SetMembers ["textfont"] = smember_textfont --alias
|
||||
SplitBarMetaFunctions.SetMembers ["textcolor"] = smember_textcolor --alias
|
||||
|
||||
SplitBarMetaFunctions.__newindex = function(_table, _key, _value)
|
||||
local func = SplitBarMetaFunctions.SetMembers [_key]
|
||||
if (func) then
|
||||
return func (_table, _value)
|
||||
else
|
||||
return rawset (_table, _key, _value)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--methods
|
||||
|
||||
--show & hide
|
||||
function SplitBarMetaFunctions:Show()
|
||||
return self.statusbar:Show()
|
||||
end
|
||||
function SplitBarMetaFunctions:Hide()
|
||||
return self.statusbar:Hide()
|
||||
end
|
||||
|
||||
-- set split
|
||||
function SplitBarMetaFunctions:SetSplit (value)
|
||||
if (not value) then
|
||||
value = self.statusbar:GetValue()
|
||||
elseif (value < 0 or value > 100) then
|
||||
return
|
||||
end
|
||||
self.statusbar:SetValue(value)
|
||||
self.spark:SetPoint("left", self.statusbar, "left", value * (self.statusbar:GetWidth()/100) - 18, 0)
|
||||
end
|
||||
|
||||
-- setpoint
|
||||
function SplitBarMetaFunctions:SetPoint(v1, v2, v3, v4, v5)
|
||||
v1, v2, v3, v4, v5 = DF:CheckPoints (v1, v2, v3, v4, v5, self)
|
||||
if (not v1) then
|
||||
print("Invalid parameter for SetPoint")
|
||||
return
|
||||
end
|
||||
return self.widget:SetPoint(v1, v2, v3, v4, v5)
|
||||
end
|
||||
|
||||
-- sizes
|
||||
function SplitBarMetaFunctions:SetSize(w, h)
|
||||
if (w) then
|
||||
self.statusbar:SetWidth(w)
|
||||
end
|
||||
if (h) then
|
||||
self.statusbar:SetHeight(h)
|
||||
end
|
||||
end
|
||||
|
||||
-- texture
|
||||
function SplitBarMetaFunctions:SetTexture(texture)
|
||||
self.rightTexture:SetTexture(texture)
|
||||
self.texture:SetTexture(texture)
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:SetBackgroundTexture(texture)
|
||||
self.background:SetTexture(texture)
|
||||
end
|
||||
|
||||
-- texts
|
||||
function SplitBarMetaFunctions:SetLeftText (text)
|
||||
self.textleft:SetText(text)
|
||||
end
|
||||
function SplitBarMetaFunctions:SetRightText (text)
|
||||
self.textright:SetText(text)
|
||||
end
|
||||
|
||||
-- colors
|
||||
function SplitBarMetaFunctions:SetLeftColor (r, g, b, a)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
self.texture:SetVertexColor(r, g, b, a)
|
||||
self.texture.original_colors = {r, g, b, a}
|
||||
end
|
||||
function SplitBarMetaFunctions:SetRightColor (r, g, b, a)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
self.rightTexture:SetVertexColor(r, g, b, a)
|
||||
self.rightTexture.original_colors = {r, g, b, a}
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:SetBackgroundColor (r, g, b, a)
|
||||
r, g, b, a = DF:ParseColors(r, g, b, a)
|
||||
self.background:SetVertexColor(r, g, b, a)
|
||||
self.background.original_colors = {r, g, b, a}
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:GetLeftColor()
|
||||
return self.texture:GetVertexColor()
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:GetRightColor()
|
||||
return self.rightTexture:GetVertexColor()
|
||||
end
|
||||
|
||||
-- icons
|
||||
function SplitBarMetaFunctions:SetLeftIcon (texture, ...)
|
||||
self.iconleft:SetTexture(texture)
|
||||
if (...) then
|
||||
local L, R, U, D = unpack(...)
|
||||
self.iconleft:SetTexCoord(L, R, U, D)
|
||||
end
|
||||
end
|
||||
function SplitBarMetaFunctions:SetRightIcon (texture, ...)
|
||||
self.iconright:SetTexture(texture)
|
||||
if (...) then
|
||||
local L, R, U, D = unpack(...)
|
||||
self.iconright:SetTexCoord(L, R, U, D)
|
||||
end
|
||||
end
|
||||
|
||||
-- tooltip
|
||||
function SplitBarMetaFunctions:SetTooltip (tooltip)
|
||||
if (tooltip) then
|
||||
return rawset (self, "have_tooltip", tooltip)
|
||||
else
|
||||
return rawset (self, "have_tooltip", nil)
|
||||
end
|
||||
end
|
||||
function SplitBarMetaFunctions:GetTooltip()
|
||||
return rawget (self, "have_tooltip")
|
||||
end
|
||||
|
||||
-- frame levels
|
||||
function SplitBarMetaFunctions:GetFrameLevel()
|
||||
return self.statusbar:GetFrameLevel()
|
||||
end
|
||||
function SplitBarMetaFunctions:SetFrameLevel(level, frame)
|
||||
if (not frame) then
|
||||
return self.statusbar:SetFrameLevel(level)
|
||||
else
|
||||
local framelevel = frame:GetFrameLevel (frame) + level
|
||||
return self.statusbar:SetFrameLevel(framelevel)
|
||||
end
|
||||
end
|
||||
|
||||
-- frame stratas
|
||||
function SplitBarMetaFunctions:SetFrameStrata(strata)
|
||||
if (type(strata) == "table") then
|
||||
self.statusbar:SetFrameStrata(strata:GetFrameStrata())
|
||||
else
|
||||
self.statusbar:SetFrameStrata(strata)
|
||||
end
|
||||
end
|
||||
|
||||
-- animation
|
||||
--animation with acceleration ~animation ~healthbaranimation
|
||||
local animateLeftWithAccel = function(self, deltaTime)
|
||||
local currentPercent = DetailsFramework:GetRangePercent(self.targetValue, self.startValue, self.currentValue)
|
||||
currentPercent = abs(currentPercent - 1)
|
||||
currentPercent = min(0.9, currentPercent)
|
||||
currentPercent = max(0.5, currentPercent)
|
||||
|
||||
local animationMultiplier = math.sin(currentPercent * math.pi)
|
||||
local valueChange = self.step * (deltaTime * animationMultiplier)
|
||||
self.currentValue = self.currentValue - valueChange
|
||||
|
||||
local barWidth = self:GetWidth()
|
||||
self.currentValue = Clamp(self.currentValue, 0, maxStatusBarValue)
|
||||
self.statusbar:SetValue(self.currentValue)
|
||||
self.rightTexture:SetWidth(barWidth - barWidth*self.currentValue)
|
||||
|
||||
if (self.currentValue - 0.001 <= self.targetValue) then
|
||||
self.targetValue = Clamp(self.targetValue, 0, maxStatusBarValue)
|
||||
self:SetValue(self.targetValue)
|
||||
self.currentValue = self.targetValue
|
||||
if (not self.SparkAlwaysShow) then
|
||||
self.spark:Hide()
|
||||
end
|
||||
self.widget:SetScript("OnUpdate", nil)
|
||||
return
|
||||
end
|
||||
|
||||
self.spark:SetPoint("center", self.widget, "left", self.currentValue * barWidth, 0)
|
||||
self.spark:Show()
|
||||
end
|
||||
|
||||
local animateRightWithAccel = function(self, deltaTime)
|
||||
--get the animation elapsed percent
|
||||
local currentPercent = DetailsFramework:GetRangePercent(self.startValue, self.targetValue, self.currentValue)
|
||||
currentPercent = min(0.9, currentPercent) --slow down the animation but avoid very slow
|
||||
currentPercent = max(0.5, currentPercent) --default: 0.1, using 0.5 makes the animation start fast and go slow
|
||||
|
||||
--get the sine value and scale time with it
|
||||
local animationMultiplier = math.sin(currentPercent * math.pi)
|
||||
local valueChange = self.step * (deltaTime * animationMultiplier)
|
||||
self.currentValue = self.currentValue + valueChange
|
||||
|
||||
local barWidth = self:GetWidth()
|
||||
self.currentValue = Clamp(self.currentValue, 0, maxStatusBarValue)
|
||||
self.statusbar:SetValue(self.currentValue)
|
||||
local rightTextureSize = barWidth - barWidth*self.currentValue
|
||||
self.rightTexture:SetWidth(rightTextureSize)
|
||||
|
||||
if (self.currentValue + 0.001 >= self.targetValue) then
|
||||
self.targetValue = Clamp(self.targetValue, 0, maxStatusBarValue)
|
||||
self:SetValue(self.targetValue)
|
||||
self.currentValue = self.targetValue
|
||||
if (not self.SparkAlwaysShow) then
|
||||
self.spark:Hide()
|
||||
end
|
||||
self.widget:SetScript("OnUpdate", nil)
|
||||
return
|
||||
end
|
||||
|
||||
self.spark:SetPoint("center", self.widget, "left", self.currentValue * barWidth, 0)
|
||||
self.spark:Show()
|
||||
end
|
||||
|
||||
local onUpdate = function(self, deltaTime)
|
||||
self = self.MyObject
|
||||
--select the animation function
|
||||
--target is always equal to current
|
||||
if (self.targetValue > self.currentValue) then
|
||||
animateRightWithAccel(self, deltaTime)
|
||||
else
|
||||
animateLeftWithAccel(self, deltaTime)
|
||||
end
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:EnableAnimations()
|
||||
return
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:DisableAnimations()
|
||||
self.widget:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
function SplitBarMetaFunctions:SetValueWithAnimation(value)
|
||||
if (self.widget:GetScript("OnUpdate") == nil) then
|
||||
self.widget:SetScript("OnUpdate", onUpdate)
|
||||
self.widget:SetMinMaxValues(0, 1)
|
||||
self.spark:ClearAllPoints()
|
||||
self.spark:SetHeight(self:GetHeight() * 2.6)
|
||||
self.spark:SetAlpha(0.4)
|
||||
end
|
||||
self.startValue = self.currentValue
|
||||
self.step = abs(value - self.currentValue)
|
||||
self.targetValue = value
|
||||
self.rightTexture:Show()
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--scripts
|
||||
|
||||
local OnEnter = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnEnter", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (frame.MyObject.have_tooltip) then
|
||||
GameCooltip2:Reset()
|
||||
GameCooltip2:AddLine(frame.MyObject.have_tooltip)
|
||||
GameCooltip2:ShowCooltip(frame, "tooltip")
|
||||
end
|
||||
end
|
||||
|
||||
local OnLeave = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnLeave", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (frame.MyObject.have_tooltip) then
|
||||
DF.popup:ShowMe(false)
|
||||
end
|
||||
end
|
||||
|
||||
local OnHide = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnHide", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnShow = function(frame)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnShow", frame, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseDown = function(frame, button)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnMouseDown", frame, button, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (not frame.MyObject.container.isLocked and frame.MyObject.container:IsMovable()) then
|
||||
if (not frame.isLocked and frame:IsMovable()) then
|
||||
frame.MyObject.container.isMoving = true
|
||||
frame.MyObject.container:StartMoving()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseUp = function(frame, button)
|
||||
local capsule = frame.MyObject
|
||||
local kill = capsule:RunHooksForWidget("OnMouseUp", frame, button, capsule)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (frame.MyObject.container.isMoving) then
|
||||
frame.MyObject.container:StopMovingOrSizing()
|
||||
frame.MyObject.container.isMoving = false
|
||||
end
|
||||
end
|
||||
|
||||
local OnSizeChanged = function(statusbar)
|
||||
statusbar.MyObject.spark:SetPoint("left", statusbar, "left", statusbar:GetValue() * (statusbar:GetWidth()/100) - 18, 0)
|
||||
statusbar.MyObject.rightTexture:SetWidth(statusbar:GetWidth() - statusbar.MyObject.texture:GetWidth())
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--object constructor
|
||||
|
||||
function DetailsFrameworkSplitlBar_OnCreate (self)
|
||||
self.texture.original_colors = {1, 1, 1, 1}
|
||||
self.rightTexture.original_colors = {.5, .5, .5, 1}
|
||||
self.spark:SetPoint("left", self, "left", self:GetValue() * (self:GetWidth()/100) - 18, 0)
|
||||
return true
|
||||
end
|
||||
|
||||
function DF:CreateSplitBar(parent, width, height, member, name)
|
||||
return DF:NewSplitBar(parent, nil, name, member, width, height)
|
||||
end
|
||||
|
||||
local build_statusbar = function(self)
|
||||
|
||||
self:SetSize(300, 14)
|
||||
|
||||
self.background = self:CreateTexture("$parent_StatusBarBackground", "BACKGROUND")
|
||||
self.background:SetPoint("topright", self, "topright")
|
||||
self.background:SetPoint("bottomright", self, "bottomright")
|
||||
self.background:SetPoint("topleft", self, "topleft")
|
||||
self.background:SetPoint("bottomleft", self, "bottomleft")
|
||||
self.background:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
self.background:SetVertexColor(.3, .3, .3, 1)
|
||||
|
||||
--this is the left texture and it grows to the right, it is embed within the bar by SetStatusBarTexture
|
||||
self.texture = self:CreateTexture("$parent_StatusBarTexture", "ARTWORK", nil, 1)
|
||||
self.texture:Hide()
|
||||
self.texture:SetSize(300, 14)
|
||||
self.texture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
|
||||
--this is the right texture and its size is the bar:GetWidth() - self.texture:GetWidth()
|
||||
self.rightTexture = self:CreateTexture("$parent_StatusBarTextureRight", "ARTWORK", nil, 2)
|
||||
self.rightTexture:Hide()
|
||||
self.rightTexture:SetSize(300, 14)
|
||||
self.rightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
|
||||
self.rightTexture:SetPoint("topright", self, "topright")
|
||||
self.rightTexture:SetPoint("bottomright", self, "bottomright")
|
||||
self.rightTexture:SetVertexColor(1, 0, 0)
|
||||
|
||||
self.lefticon = self:CreateTexture("$parent_IconLeft", "OVERLAY")
|
||||
self.lefticon:SetSize(14, 14)
|
||||
self.lefticon:SetPoint("LEFT", self, "LEFT")
|
||||
|
||||
self.righticon = self:CreateTexture("$parent_IconRight", "OVERLAY")
|
||||
self.righticon:SetSize(14, 14)
|
||||
self.righticon:SetPoint("RIGHT", self, "RIGHT")
|
||||
|
||||
self.spark = self:CreateTexture("$parent_Spark", "OVERLAY")
|
||||
self.spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
self.spark:SetBlendMode("ADD")
|
||||
self.spark:SetSize(32, 32)
|
||||
self.spark:SetPoint("LEFT", self, "RIGHT", -17, -1)
|
||||
|
||||
self.lefttext = self:CreateFontString("$parent_TextLeft", "OVERLAY", "GameFontHighlight")
|
||||
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)
|
||||
self.righttext:SetJustifyH("right")
|
||||
self.righttext:SetPoint("RIGHT", self.righticon, "LEFT", -3, 0)
|
||||
|
||||
self:SetStatusBarTexture(self.texture)
|
||||
self:SetMinMaxValues(1, 100)
|
||||
self:SetValue(50)
|
||||
DetailsFrameworkSplitlBar_OnCreate (self)
|
||||
end
|
||||
|
||||
|
||||
function DF:NewSplitBar (parent, container, name, member, w, h)
|
||||
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkSplitbar" .. DF.SplitBarCounter
|
||||
DF.SplitBarCounter = DF.SplitBarCounter + 1
|
||||
end
|
||||
if (not parent) then
|
||||
return error("Details! FrameWork: parent not found.", 2)
|
||||
end
|
||||
if (not container) then
|
||||
container = parent
|
||||
end
|
||||
|
||||
if (name:find("$parent")) then
|
||||
local parentName = DF.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
|
||||
local SplitBarObject = {type = "barsplit", dframework = true}
|
||||
|
||||
if (member) then
|
||||
parent [member] = SplitBarObject
|
||||
end
|
||||
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
if (container.dframework) then
|
||||
container = container.widget
|
||||
end
|
||||
|
||||
--default members:
|
||||
--misc
|
||||
SplitBarObject.locked = false
|
||||
SplitBarObject.container = container
|
||||
SplitBarObject.currentValue = 0.5
|
||||
|
||||
--create widgets
|
||||
SplitBarObject.statusbar = CreateFrame("statusbar", name, parent, "BackdropTemplate")
|
||||
build_statusbar (SplitBarObject.statusbar)
|
||||
SplitBarObject.spark = SplitBarObject.statusbar.spark
|
||||
SplitBarObject.widget = SplitBarObject.statusbar
|
||||
|
||||
if (not APISplitBarFunctions) then
|
||||
APISplitBarFunctions = true
|
||||
local idx = getmetatable(SplitBarObject.statusbar).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not SplitBarMetaFunctions [funcName]) then
|
||||
SplitBarMetaFunctions [funcName] = function(object, ...)
|
||||
local x = loadstring ( "return _G['"..object.statusbar:GetName().."']:"..funcName.."(...)")
|
||||
return x (...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SplitBarObject.statusbar:SetHeight(h or 200)
|
||||
SplitBarObject.statusbar:SetWidth(w or 14)
|
||||
SplitBarObject.statusbar:SetValue(0.5)
|
||||
|
||||
SplitBarObject.statusbar.MyObject = SplitBarObject
|
||||
|
||||
SplitBarObject.textleft = _G [name .. "_TextLeft"]
|
||||
SplitBarObject.textright = _G [name .. "_TextRight"]
|
||||
|
||||
SplitBarObject.iconleft = _G [name .. "_IconLeft"]
|
||||
SplitBarObject.iconright = _G [name .. "_IconRight"]
|
||||
|
||||
SplitBarObject.background = _G [name .. "_StatusBarBackground"]
|
||||
SplitBarObject.texture = _G [name .. "_StatusBarTexture"]
|
||||
SplitBarObject.rightTexture = _G [name .. "_StatusBarTextureRight"]
|
||||
|
||||
--hooks
|
||||
SplitBarObject.HookList = {
|
||||
OnEnter = {},
|
||||
OnLeave = {},
|
||||
OnHide = {},
|
||||
OnShow = {},
|
||||
OnMouseDown = {},
|
||||
OnMouseUp = {},
|
||||
OnSizeChanged = {},
|
||||
}
|
||||
|
||||
SplitBarObject.statusbar:SetScript("OnEnter", OnEnter)
|
||||
SplitBarObject.statusbar:SetScript("OnLeave", OnLeave)
|
||||
SplitBarObject.statusbar:SetScript("OnHide", OnHide)
|
||||
SplitBarObject.statusbar:SetScript("OnShow", OnShow)
|
||||
SplitBarObject.statusbar:SetScript("OnMouseDown", OnMouseDown)
|
||||
SplitBarObject.statusbar:SetScript("OnMouseUp", OnMouseUp)
|
||||
SplitBarObject.statusbar:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
|
||||
setmetatable(SplitBarObject, SplitBarMetaFunctions)
|
||||
|
||||
return SplitBarObject
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
|
||||
<Script file="split_bar.lua"/>
|
||||
</Ui>
|
||||
@@ -1,422 +0,0 @@
|
||||
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local PixelUtil = PixelUtil
|
||||
|
||||
---@class df_tabinfotable : {name: string, text: string}
|
||||
|
||||
---@class df_tabcontainer : frame
|
||||
---@field AllFrames df_tabcontainerframe[]
|
||||
---@field AllButtons df_tabcontainerbutton[]
|
||||
---@field AllFramesByName table<string, df_tabcontainerframe>
|
||||
---@field AllButtonsByName table<string, df_tabcontainerbutton>
|
||||
---@field hookList table
|
||||
---@field CurrentIndex number
|
||||
---@field IsContainer boolean
|
||||
---@field ButtonSelectedBorderColor table
|
||||
---@field ButtonNotSelectedBorderColor table
|
||||
---@field CanCloseWithRightClick boolean
|
||||
---@field SetIndex fun(self: df_tabcontainer, index: number)
|
||||
---@field SelectTabByIndex fun(self: df_tabcontainer, menuIndex: number)
|
||||
---@field SelectTabByName fun(self: df_tabcontainer, name: string)
|
||||
---@field CreateUnderlineGlow fun(button: button)
|
||||
---@field OnShow fun(self: df_tabcontainer)
|
||||
---@field GetTabFrameByName fun(self: df_tabcontainer, name: string): df_tabcontainerframe
|
||||
---@field GetTabFrameByIndex fun(self: df_tabcontainer, index: number): df_tabcontainerframe
|
||||
---@field GetTabButtonByName fun(self: df_tabcontainer, name: string): df_tabcontainerbutton
|
||||
---@field GetTabButtonByIndex fun(self: df_tabcontainer, index: number): df_tabcontainerbutton
|
||||
|
||||
---@class df_tabcontainerframe : frame
|
||||
---@field bIsFrontPage boolean
|
||||
---@field titleText fontstring
|
||||
---@field tabIndex number
|
||||
---@field OnMouseDown fun(self: df_tabcontainerframe, button: string)
|
||||
---@field OnMouseUp fun(self: df_tabcontainerframe, button: string)
|
||||
---@field RefreshOptions fun(self: df_tabcontainerframe)|nil
|
||||
|
||||
---@class df_tabcontainerbutton : button
|
||||
---@field selectedUnderlineGlow texture
|
||||
---@field textsize number
|
||||
---@field mainFrame df_tabcontainer
|
||||
---@field leftSelectionIndicator texture
|
||||
|
||||
--create a template for the tab buttons
|
||||
local tabTemplate = detailsFramework.table.copy({}, detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
tabTemplate.backdropbordercolor = nil
|
||||
|
||||
detailsFramework.TabContainerMixin = {
|
||||
---@param self df_tabcontainer
|
||||
---@param tabIndex number
|
||||
---@return df_tabcontainerframe
|
||||
GetTabFrameByIndex = function(self, tabIndex)
|
||||
return self.AllFrames[tabIndex]
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
---@param name string
|
||||
---@return df_tabcontainerframe
|
||||
GetTabFrameByName = function(self, name)
|
||||
return self.AllFramesByName[name]
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
---@param tabIndex number
|
||||
---@return df_tabcontainerbutton
|
||||
GetTabButtonByIndex = function(self, tabIndex)
|
||||
return self.AllButtons[tabIndex]
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
---@param name string
|
||||
---@return df_tabcontainerbutton
|
||||
GetTabButtonByName = function(self, name)
|
||||
return self.AllButtonsByName[name]
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
---@param backdropTable backdrop|nil
|
||||
---@param backdropColorTable table|string|nil
|
||||
---@param backdropBorderColorTable table|string|nil
|
||||
SetTabFramesBackdrop = function(self, backdropTable, backdropColorTable, backdropBorderColorTable)
|
||||
for tabIndex, tabFrame in ipairs(self.AllFrames) do
|
||||
if (backdropTable) then
|
||||
tabFrame:SetBackdrop(backdropTable)
|
||||
end
|
||||
if (backdropColorTable) then
|
||||
local r, g, b, a = detailsFramework:ParseColors(backdropColorTable)
|
||||
tabFrame:SetBackdropColor(r, g, b, a)
|
||||
end
|
||||
if (backdropBorderColorTable) then
|
||||
local r, g, b, a = detailsFramework:ParseColors(backdropColorTable)
|
||||
tabFrame:SetBackdropBorderColor(r, g, b, a)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---create a underglow texture for the selected tab, this texture is a small yellow bright gradient below the button
|
||||
---@param self df_tabcontainerbutton
|
||||
CreateUnderlineGlow = function(self)
|
||||
local selectedGlow = self:CreateTexture(nil, "background", nil, -4)
|
||||
selectedGlow:SetPoint("topleft", self["widget"], "bottomleft", -7, 0)
|
||||
selectedGlow:SetPoint("topright", self["widget"], "bottomright", 7, 0)
|
||||
selectedGlow:SetTexture([[Interface\BUTTONS\UI-Panel-Button-Glow]])
|
||||
selectedGlow:SetTexCoord(0, 95/128, 30/64, 38/64)
|
||||
selectedGlow:SetBlendMode("ADD")
|
||||
selectedGlow:SetHeight(8)
|
||||
selectedGlow:SetAlpha(.75)
|
||||
selectedGlow:Hide()
|
||||
self.selectedUnderlineGlow = selectedGlow
|
||||
end,
|
||||
|
||||
---@param tabContainer df_tabcontainer
|
||||
---@param menuIndex number
|
||||
SelectTabByIndex = function(tabContainer, menuIndex)
|
||||
---@type df_tabcontainerbutton
|
||||
local tabButton = tabContainer.AllButtons[menuIndex]
|
||||
---@type df_tabcontainerframe
|
||||
local tabFrame = tabContainer.AllFrames[menuIndex]
|
||||
|
||||
--hide all tab frame and hide the selection glow from tab buttons
|
||||
for i = 1, #tabContainer.AllFrames do
|
||||
---@type df_tabcontainerframe
|
||||
local thisTabFrame = tabContainer.AllFrames[i]
|
||||
thisTabFrame:Hide()
|
||||
|
||||
---@type df_tabcontainerbutton
|
||||
local thisTabButton = tabContainer.AllButtons[i]
|
||||
if (tabContainer.ButtonNotSelectedBorderColor) then
|
||||
thisTabButton:SetBackdropBorderColor(unpack(tabContainer.ButtonNotSelectedBorderColor))
|
||||
end
|
||||
if (thisTabButton.selectedUnderlineGlow) then
|
||||
thisTabButton.selectedUnderlineGlow:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
tabFrame:Show()
|
||||
if (tabFrame.RefreshOptions) then
|
||||
tabFrame:RefreshOptions()
|
||||
end
|
||||
|
||||
if (tabContainer.ButtonSelectedBorderColor) then
|
||||
tabButton:SetBackdropBorderColor(unpack(tabContainer.ButtonSelectedBorderColor))
|
||||
end
|
||||
|
||||
if (tabButton.selectedUnderlineGlow) then
|
||||
tabButton.selectedUnderlineGlow:Show()
|
||||
end
|
||||
|
||||
tabContainer.CurrentIndex = menuIndex
|
||||
|
||||
if (tabContainer.hookList.OnSelectIndex) then
|
||||
detailsFramework:QuickDispatch(tabContainer.hookList.OnSelectIndex, tabContainer, tabButton)
|
||||
end
|
||||
end,
|
||||
|
||||
---@param tabContainer df_tabcontainer
|
||||
---@param name string
|
||||
SelectTabByName = function(tabContainer, name)
|
||||
---@type df_tabcontainerframe
|
||||
local tabFrame = tabContainer.AllFramesByName[name]
|
||||
if (tabFrame) then
|
||||
local tabIndex = tabFrame.tabIndex
|
||||
tabContainer:SelectTabByIndex(tabIndex)
|
||||
else
|
||||
error("df_tabcontainer:SelectTabByName(name): param #2 'name' not found within 'tabContainer.AllFramesByName'.")
|
||||
end
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
---@param index number
|
||||
SetIndex = function(self, index)
|
||||
self.CurrentIndex = index
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainer
|
||||
OnShow = function(self)
|
||||
local index = self.CurrentIndex
|
||||
self:SelectTabByIndex(index)
|
||||
end
|
||||
}
|
||||
|
||||
detailsFramework.TabContainerFrameMixin = {
|
||||
---@param self df_tabcontainerframe
|
||||
---@param button string
|
||||
OnMouseDown = function(self, button)
|
||||
--search for UIParent
|
||||
---@type frame
|
||||
local highestParent = detailsFramework:FindHighestParent(self)
|
||||
local tabContainer = self:GetParent()
|
||||
---@cast tabContainer df_tabcontainer
|
||||
|
||||
if (button == "LeftButton") then
|
||||
if (not highestParent.IsMoving and highestParent:IsMovable()) then
|
||||
highestParent:StartMoving()
|
||||
highestParent.IsMoving = true
|
||||
end
|
||||
|
||||
elseif (button == "RightButton") then
|
||||
if (not highestParent.IsMoving and tabContainer.IsContainer) then
|
||||
if (self.bIsFrontPage) then
|
||||
if (tabContainer.CanCloseWithRightClick) then
|
||||
if (highestParent["CloseFunction"]) then
|
||||
highestParent["CloseFunction"](highestParent)
|
||||
else
|
||||
highestParent:Hide()
|
||||
end
|
||||
end
|
||||
else
|
||||
--goes back to front page
|
||||
tabContainer:SelectTabByIndex(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---@param self df_tabcontainerframe
|
||||
---@param button string
|
||||
OnMouseUp = function(self, button)
|
||||
local frame = detailsFramework:FindHighestParent(self)
|
||||
if (frame.IsMoving) then
|
||||
frame:StopMovingOrSizing()
|
||||
frame.IsMoving = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---creates a frame called tabContainer which is used as base for the tab container object
|
||||
---the function receives a table called tabList which contains sub tables with two keys 'name' and 'text', name is the frame name and text is the text displayed on the button
|
||||
---then the function iterate amongst the tabList and create a frame and a button for each entry using the value of the 'text' key as the text for the button and 'name' for the name of the frame
|
||||
---when the user click on a button, the tabContainer hide all frames and show the frame which was created together with that button
|
||||
---@param parent frame the parent frame
|
||||
---@param title string a string to use as the title of the tab container, the title is always shown
|
||||
---@param frameName string the frame name to pass into the CreateFrame function
|
||||
---@param tabList df_tabinfotable[] the list of tabs to create, each entry has a 'name' and 'text' keys
|
||||
---@param optionsTable {button_border_color: table, button_selected_border_color: table, right_click_y: number, hide_click_label: boolean, close_text_alpha: number, rightbutton_always_close: boolean, right_click_interact: boolean, y_offset: number, button_width: number, button_height: number, button_x: number, button_y: number, button_text_size: number, container_width_offset: number}|nil
|
||||
---@param hookList table<string, function>|nil
|
||||
---@param languageInfo any
|
||||
---@return df_tabcontainer
|
||||
function detailsFramework:CreateTabContainer(parent, title, frameName, tabList, optionsTable, hookList, languageInfo)
|
||||
optionsTable = optionsTable or {}
|
||||
|
||||
local parentFrameWidth = parent:GetWidth()
|
||||
local yOffset = optionsTable.y_offset or 0
|
||||
local buttonWidth = optionsTable.button_width or 160
|
||||
local buttonHeight = optionsTable.button_height or 20
|
||||
local buttonAnchorX = optionsTable.button_x or 230
|
||||
local buttonAnchorY = optionsTable.button_y or 0
|
||||
local buttonTextSize = optionsTable.button_text_size or 10
|
||||
local containerWidthOffset = optionsTable.container_width_offset or 0
|
||||
|
||||
--create the base frame
|
||||
---@type df_tabcontainer
|
||||
local tabContainer = CreateFrame("frame", frameName, parent["widget"] or parent, "BackdropTemplate")
|
||||
tabContainer.hookList = hookList or {}
|
||||
|
||||
detailsFramework:Mixin(tabContainer, detailsFramework.TabContainerMixin)
|
||||
|
||||
--create the fontstring which show the title
|
||||
---@type fontstring
|
||||
local mainTitle = detailsFramework:CreateLabel(tabContainer, title, 24, "white")
|
||||
mainTitle:SetPoint("topleft", tabContainer, "topleft", 10, -30 + yOffset)
|
||||
|
||||
tabContainer.AllFrames = {}
|
||||
tabContainer.AllButtons = {}
|
||||
tabContainer.AllFramesByName = {}
|
||||
tabContainer.AllButtonsByName = {}
|
||||
tabContainer.CurrentIndex = 1
|
||||
tabContainer.IsContainer = true
|
||||
tabContainer.ButtonSelectedBorderColor = optionsTable.button_selected_border_color or {1, 1, 0, 1}
|
||||
tabContainer.ButtonNotSelectedBorderColor = optionsTable.button_border_color or {0, 0, 0, 0}
|
||||
|
||||
if (optionsTable.right_click_interact ~= nil) then
|
||||
tabContainer.CanCloseWithRightClick = optionsTable.right_click_interact
|
||||
else
|
||||
tabContainer.CanCloseWithRightClick = true
|
||||
end
|
||||
|
||||
--languageInfo
|
||||
local addonId = languageInfo and languageInfo.language_addonId or "none"
|
||||
|
||||
for tabIndex, tabInfo in ipairs(tabList) do
|
||||
--create a frame which will be shown when the tabButton is clicked
|
||||
--when this tab isn't selected, this frame is hidden
|
||||
---@type df_tabcontainerframe
|
||||
local tabFrame = CreateFrame("frame", "$parent" .. tabInfo.name, tabContainer, "BackdropTemplate")
|
||||
detailsFramework:Mixin(tabFrame, detailsFramework.TabContainerFrameMixin)
|
||||
tabFrame:SetAllPoints()
|
||||
tabFrame:SetFrameLevel(210)
|
||||
tabFrame:SetScript("OnMouseDown", tabFrame.OnMouseDown)
|
||||
tabFrame:SetScript("OnMouseUp", tabFrame.OnMouseUp)
|
||||
tabFrame.tabIndex = tabIndex
|
||||
tabFrame:Hide()
|
||||
|
||||
--attempt to get the localized text from the language system using the addonId and the frameInfo.text
|
||||
local phraseId = tabInfo.text
|
||||
local bIsLanguagePrahseID = detailsFramework.Language.DoesPhraseIDExistsInDefaultLanguage(addonId, phraseId)
|
||||
|
||||
--create the fontstring which show this tab text, this text is only shown when the tab is shown
|
||||
local titleLabel = detailsFramework:CreateLabel(tabFrame, "", 16, "silver")
|
||||
if (bIsLanguagePrahseID) then
|
||||
DetailsFramework.Language.RegisterObjectWithDefault(addonId, titleLabel, tabInfo.text, tabInfo.text)
|
||||
else
|
||||
titleLabel:SetText(tabInfo.text)
|
||||
end
|
||||
titleLabel:SetPoint("topleft", mainTitle, "bottomleft", 0, 0)
|
||||
tabFrame.titleText = titleLabel
|
||||
|
||||
---@type df_tabcontainerbutton
|
||||
local tabButton = detailsFramework:CreateButton(tabContainer, function() tabContainer:SelectTabByIndex(tabIndex) end, buttonWidth, buttonHeight, tabInfo.text, tabIndex, nil, nil, nil, "$parentTabButton" .. tabInfo.name, false, tabTemplate)
|
||||
PixelUtil.SetSize(tabButton, buttonWidth, buttonHeight)
|
||||
tabButton:SetFrameLevel(220)
|
||||
tabButton.textsize = buttonTextSize
|
||||
tabButton.mainFrame = tabContainer
|
||||
tabContainer.CreateUnderlineGlow(tabButton)
|
||||
|
||||
--register the fontstring with the language system
|
||||
if (bIsLanguagePrahseID) then
|
||||
DetailsFramework.Language.RegisterObjectWithDefault(addonId, tabButton["widget"], tabInfo.text, tabInfo.text)
|
||||
end
|
||||
|
||||
local rightClickToBack
|
||||
if (tabIndex == 1 or optionsTable.rightbutton_always_close) then
|
||||
rightClickToBack = detailsFramework:CreateLabel(tabFrame, "right click to close", 10, "gray")
|
||||
rightClickToBack:SetPoint("bottomright", tabFrame, "bottomright", -1, optionsTable.right_click_y or 0)
|
||||
if (optionsTable.close_text_alpha) then
|
||||
rightClickToBack:SetAlpha(optionsTable.close_text_alpha)
|
||||
end
|
||||
tabFrame.bIsFrontPage = true
|
||||
else
|
||||
rightClickToBack = detailsFramework:CreateLabel(tabFrame, "right click to go back to main menu", 10, "gray")
|
||||
rightClickToBack:SetPoint("bottomright", tabFrame, "bottomright", -1, optionsTable.right_click_y or 0)
|
||||
if (optionsTable.close_text_alpha) then
|
||||
rightClickToBack:SetAlpha(optionsTable.close_text_alpha)
|
||||
end
|
||||
end
|
||||
|
||||
if (optionsTable.hide_click_label) then
|
||||
rightClickToBack:Hide()
|
||||
end
|
||||
|
||||
table.insert(tabContainer.AllFrames, tabFrame)
|
||||
table.insert(tabContainer.AllButtons, tabButton)
|
||||
tabContainer.AllFramesByName[tabInfo.name] = tabFrame
|
||||
tabContainer.AllFramesByName[tabInfo.text] = tabFrame
|
||||
tabContainer.AllButtonsByName[tabInfo.name] = tabButton
|
||||
tabContainer.AllButtonsByName[tabInfo.text] = tabButton
|
||||
end
|
||||
|
||||
--order buttons
|
||||
local x = buttonAnchorX
|
||||
local y = buttonAnchorY
|
||||
local spaceBetweenButtons = 3
|
||||
|
||||
local allocatedSpaceForButtons = parentFrameWidth - ((#tabList - 2) * spaceBetweenButtons) - buttonAnchorX + containerWidthOffset
|
||||
local amountButtonsPerRow = math.floor(allocatedSpaceForButtons / buttonWidth)
|
||||
|
||||
tabContainer.AllButtons[1]:SetPoint("topleft", mainTitle, "topleft", x, y)
|
||||
x = x + buttonWidth + 2
|
||||
|
||||
for i = 2, #tabContainer.AllButtons do
|
||||
local button = tabContainer.AllButtons[i]
|
||||
PixelUtil.SetPoint(button, "topleft", mainTitle, "topleft", x, y)
|
||||
x = x + buttonWidth + 2
|
||||
|
||||
if (i % amountButtonsPerRow == 0) then
|
||||
x = buttonAnchorX
|
||||
y = y - buttonHeight - 1
|
||||
end
|
||||
end
|
||||
|
||||
--when show the frame, reset to the current internal index
|
||||
tabContainer:SetScript("OnShow", tabContainer.OnShow)
|
||||
--select the first frame
|
||||
local defaultTab = 1
|
||||
tabContainer:SelectTabByIndex(defaultTab)
|
||||
|
||||
return tabContainer
|
||||
end
|
||||
|
||||
|
||||
--[=[example:
|
||||
|
||||
local parent = UIParent
|
||||
local title = "My AddOn Options"
|
||||
local frameName = "MyAddOnOptionsFrame"
|
||||
local tabList = {
|
||||
{name = "GeneralSettings", text = "General Settings"},
|
||||
{name = "AdvancedSettings", text = "Advanced Settings"},
|
||||
{name = "AboutTheAddon", text = "Addon Info"},
|
||||
}
|
||||
local optionsTable = {}
|
||||
local hookList = {}
|
||||
local languageInfo = {language_addonId = "MyAddOnTocName"}
|
||||
|
||||
local tabContainer = DetailsFramework:CreateTabContainer(parent, title, frameName, tabList, optionsTable, hookList, languageInfo)
|
||||
tabContainer:SetPoint("center", UIParent, "center", 0, 0)
|
||||
tabContainer:SetSize(750, 450)
|
||||
tabContainer:Show()
|
||||
|
||||
--ways for getting a tab frame and start to create widgets inside it
|
||||
local tabIndex = 1
|
||||
local generalSettingsTabFrame = tabContainer:GetTabFrameByIndex(tabIndex) --using a tabIndex
|
||||
local advancedSettingsTabFrame = tabContainer:GetTabFrameByName("Advanced Settings") --using the tab text
|
||||
local aboutTabFrame = tabContainer:GetTabFrameByName("AboutTheAddon") --using the tab name
|
||||
|
||||
--clicking on tab buttons will automatically show the tab frame, to select a tab frame without clicking on the button, use:
|
||||
tabContainer:SelectTabByIndex(tabIndex) --using a tabIndex
|
||||
tabContainer:SelectTabByName("Advanced Settings") --using the tab text
|
||||
tabContainer:SelectTabByName("AdvancedSettings") --using the tab name
|
||||
|
||||
--modify the background color by applying a backdrop
|
||||
local backdropTable = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}
|
||||
local backdropColor = {DetailsFramework:GetDefaultBackdropColor()}
|
||||
local backdropBorderColor = {0, 0, 0, 1}
|
||||
tabContainer:SetTabFramesBackdrop(backdropTable, backdropColor, backdropBorderColor)
|
||||
|
||||
--]=]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
|
||||
<Script file="textentry.lua"/>
|
||||
</Ui>
|
||||
@@ -1,462 +0,0 @@
|
||||
|
||||
local DF = _G["DetailsFramework"]
|
||||
if (not DF or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local _
|
||||
local type = type
|
||||
local floor = math.floor
|
||||
local GetTime = GetTime
|
||||
|
||||
local APITimeBarFunctions
|
||||
|
||||
do
|
||||
local metaPrototype = {
|
||||
WidgetType = "timebar",
|
||||
dversion = DF.dversion,
|
||||
}
|
||||
|
||||
--check if there's a metaPrototype already existing
|
||||
if (_G[DF.GlobalWidgetControlNames["timebar"]]) then
|
||||
--get the already existing metaPrototype
|
||||
local oldMetaPrototype = _G[DF.GlobalWidgetControlNames["timebar"]]
|
||||
--check if is older
|
||||
if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < DF.dversion) ) then
|
||||
--the version is older them the currently loading one
|
||||
--copy the new values into the old metatable
|
||||
for funcName, _ in pairs(metaPrototype) do
|
||||
oldMetaPrototype[funcName] = metaPrototype[funcName]
|
||||
end
|
||||
end
|
||||
else
|
||||
--first time loading the framework
|
||||
_G[DF.GlobalWidgetControlNames["timebar"]] = metaPrototype
|
||||
end
|
||||
end
|
||||
|
||||
local TimeBarMetaFunctions = _G[DF.GlobalWidgetControlNames["timebar"]]
|
||||
DF:Mixin(TimeBarMetaFunctions, DF.ScriptHookMixin)
|
||||
|
||||
--methods
|
||||
TimeBarMetaFunctions.SetMembers = TimeBarMetaFunctions.SetMembers or {}
|
||||
TimeBarMetaFunctions.GetMembers = TimeBarMetaFunctions.GetMembers or {}
|
||||
|
||||
TimeBarMetaFunctions.__index = function(table, key)
|
||||
local func = TimeBarMetaFunctions.GetMembers[key]
|
||||
if (func) then
|
||||
return func(table, key)
|
||||
end
|
||||
|
||||
local fromMe = rawget(table, key)
|
||||
if (fromMe) then
|
||||
return fromMe
|
||||
end
|
||||
|
||||
return TimeBarMetaFunctions[key]
|
||||
end
|
||||
|
||||
TimeBarMetaFunctions.__newindex = function(table, key, value)
|
||||
local func = TimeBarMetaFunctions.SetMembers[key]
|
||||
if (func) then
|
||||
return func(table, value)
|
||||
else
|
||||
return rawset(table, key, value)
|
||||
end
|
||||
end
|
||||
|
||||
--scripts
|
||||
local OnEnterFunc = function(statusBar)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnEnter", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (statusBar.MyObject.tooltip) then
|
||||
GameCooltip2:Reset()
|
||||
GameCooltip2:AddLine(statusBar.MyObject.tooltip)
|
||||
GameCooltip2:ShowCooltip(statusBar, "tooltip")
|
||||
end
|
||||
end
|
||||
|
||||
local OnLeaveFunc = function(statusBar)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnLeave", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
|
||||
if (statusBar.MyObject.tooltip) then
|
||||
GameCooltip2:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local OnHideFunc = function(statusBar)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnHide", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnShowFunc = function(statusBar)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnShow", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseDownFunc = function(statusBar, mouseButton)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnMouseDown", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local OnMouseUpFunc = function(statusBar, mouseButton)
|
||||
local kill = statusBar.MyObject:RunHooksForWidget("OnMouseUp", statusBar, statusBar.MyObject)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--timer functions
|
||||
function TimeBarMetaFunctions:SetIconSize(width, height)
|
||||
if (width and not height) then
|
||||
self.statusBar.icon:SetWidth(width)
|
||||
|
||||
elseif (not width and height) then
|
||||
self.statusBar.icon:SetHeight(height)
|
||||
|
||||
elseif (width and height) then
|
||||
self.statusBar.icon:SetSize(width, height)
|
||||
end
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetIcon(texture, L, R, T, B)
|
||||
if (texture) then
|
||||
self.statusBar.icon:Show()
|
||||
self.statusBar.icon:SetPoint("left", self.statusBar, "left", 2, 0)
|
||||
self.statusBar.icon:SetSize(self.statusBar:GetHeight()-2, self.statusBar:GetHeight()-2)
|
||||
self.statusBar.leftText:ClearAllPoints()
|
||||
self.statusBar.leftText:SetPoint("left", self.statusBar.icon, "right", 2, 0)
|
||||
self.statusBar.icon:SetTexture(texture)
|
||||
|
||||
if (L) then
|
||||
self.statusBar.icon:SetTexCoord(L, R, T, B)
|
||||
end
|
||||
else
|
||||
self.statusBar.icon:Hide()
|
||||
self.statusBar.leftText:ClearAllPoints()
|
||||
self.statusBar.leftText:SetPoint("left", self.statusBar, "left", 2, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:GetIcon()
|
||||
return self.statusBar.icon
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetTexture(texture)
|
||||
self.statusBar.barTexture:SetTexture(texture)
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetColor(color, green, blue, alpha)
|
||||
local r, g, b, a = DF:ParseColors(color, green, blue, alpha)
|
||||
self.statusBar.barTexture:SetVertexColor(r, g, b, a)
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetLeftText(text)
|
||||
self.statusBar.leftText:SetText(text)
|
||||
end
|
||||
function TimeBarMetaFunctions:SetRightText(text)
|
||||
self.statusBar.rightText:SetText(text)
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetFont(font, size, color, shadow)
|
||||
if (font) then
|
||||
DF:SetFontFace(self.statusBar.leftText, font)
|
||||
end
|
||||
|
||||
if (size) then
|
||||
DF:SetFontSize(self.statusBar.leftText, size)
|
||||
end
|
||||
|
||||
if (color) then
|
||||
DF:SetFontColor(self.statusBar.leftText, color)
|
||||
end
|
||||
|
||||
if (shadow) then
|
||||
DF:SetFontOutline(self.statusBar.leftText, shadow)
|
||||
end
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetThrottle(seconds)
|
||||
if (seconds and seconds > 0) then
|
||||
self.statusBar.isUsingThrottle = true
|
||||
self.statusBar.amountThrottle = seconds
|
||||
else
|
||||
self.statusBar.isUsingThrottle = false
|
||||
end
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetDirection(direction)
|
||||
direction = direction or "right"
|
||||
self.direction = direction
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:HasTimer()
|
||||
return self.statusBar.hasTimer
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:StopTimer()
|
||||
if (self.statusBar.hasTimer) then
|
||||
self.statusBar.hasTimer = nil
|
||||
local kill = self:RunHooksForWidget("OnTimerEnd", self.statusBar, self)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local statusBar = self.statusBar
|
||||
statusBar:SetScript("OnUpdate", nil)
|
||||
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetValue(100)
|
||||
statusBar.rightText:SetText("")
|
||||
|
||||
statusBar.spark:Hide()
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:ShowSpark(state, alpha, color)
|
||||
if (type(state) == "boolean" and state == false) then
|
||||
self.statusBar.dontShowSpark = true
|
||||
else
|
||||
self.statusBar.dontShowSpark = nil
|
||||
end
|
||||
|
||||
if (alpha) then
|
||||
self.statusBar.sparkAlpha = alpha
|
||||
else
|
||||
self.statusBar.sparkAlpha = nil
|
||||
end
|
||||
|
||||
if (color) then
|
||||
local r, g, b = DF:ParseColors(color)
|
||||
if (r and g and b) then
|
||||
self.statusBar.sparkColorR = r
|
||||
self.statusBar.sparkColorG = g
|
||||
self.statusBar.sparkColorB = b
|
||||
end
|
||||
else
|
||||
self.statusBar.sparkColorR = nil
|
||||
self.statusBar.sparkColorG = nil
|
||||
self.statusBar.sparkColorB = nil
|
||||
end
|
||||
end
|
||||
|
||||
local OnUpdateFunc = function(self, deltaTime)
|
||||
if (self.isUsingThrottle) then
|
||||
self.throttle = self.throttle + deltaTime
|
||||
if (self.throttle < self.amountThrottle) then
|
||||
return
|
||||
end
|
||||
self.throttle = 0
|
||||
end
|
||||
|
||||
local timeNow = GetTime()
|
||||
self:SetValue(timeNow)
|
||||
|
||||
--adjust the spark
|
||||
local spark = self.spark
|
||||
local startTime, endTime = self:GetMinMaxValues()
|
||||
|
||||
if (not self.dontShowSpark) then
|
||||
if (self.direction == "right") then
|
||||
local pct = abs((timeNow - endTime) / (endTime - startTime))
|
||||
pct = abs(1 - pct)
|
||||
spark:SetPoint("left", self, "left", (self:GetWidth() * pct) - 16, 0)
|
||||
spark:Show()
|
||||
else
|
||||
spark:SetPoint("right", self, "right", self:GetWidth() * (timeNow/self.endTime), 0)
|
||||
end
|
||||
end
|
||||
|
||||
local timeLeft = floor(endTime - timeNow)
|
||||
local formatedTimeLeft = DF:IntegerToTimer(timeLeft)
|
||||
self.rightText:SetText(formatedTimeLeft)
|
||||
|
||||
--check if finished
|
||||
if (timeNow >= self.endTime) then
|
||||
self.MyObject:StopTimer()
|
||||
end
|
||||
end
|
||||
|
||||
function TimeBarMetaFunctions:SetTimer(currentTime, startTime, endTime)
|
||||
self.statusBar:Show()
|
||||
|
||||
if (not currentTime or currentTime == 0) then
|
||||
self:StopTimer()
|
||||
return
|
||||
end
|
||||
|
||||
if (startTime and endTime) then
|
||||
if (self.statusBar.hasTimer and currentTime == self.statusBar.timeLeft1) then
|
||||
--it is the same timer called again
|
||||
return
|
||||
end
|
||||
self.statusBar.startTime = startTime
|
||||
self.statusBar.endTime = endTime
|
||||
else
|
||||
local bForceNewTimer = type(startTime) == "boolean" and startTime
|
||||
if (self.statusBar.hasTimer and currentTime == self.statusBar.timeLeft2 and not bForceNewTimer) then
|
||||
--it is the same timer called again
|
||||
return
|
||||
end
|
||||
self.statusBar.startTime = GetTime()
|
||||
self.statusBar.endTime = GetTime() + currentTime
|
||||
self.statusBar.timeLeft2 = currentTime
|
||||
end
|
||||
|
||||
self.statusBar:SetMinMaxValues(self.statusBar.startTime, self.statusBar.endTime)
|
||||
|
||||
if (self.direction == "right") then
|
||||
self.statusBar:SetReverseFill(false)
|
||||
else
|
||||
self.statusBar:SetReverseFill(true)
|
||||
end
|
||||
|
||||
if (self.statusBar.dontShowSpark) then
|
||||
self.statusBar.spark:Hide()
|
||||
else
|
||||
self.statusBar.spark:Show()
|
||||
self.statusBar.spark:SetHeight(self.statusBar:GetHeight()+20)
|
||||
|
||||
if (self.statusBar.sparkAlpha) then
|
||||
self.statusBar.spark:SetAlpha(self.statusBar.sparkAlpha)
|
||||
else
|
||||
self.statusBar.spark:SetAlpha(1)
|
||||
end
|
||||
|
||||
if (self.statusBar.sparkColorR) then
|
||||
self.statusBar.spark:SetVertexColor(self.statusBar.sparkColorR, self.statusBar.sparkColorG, self.statusBar.sparkColorB)
|
||||
else
|
||||
self.statusBar.spark:SetVertexColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
|
||||
self.statusBar.hasTimer = true
|
||||
self.statusBar.direction = self.direction
|
||||
self.statusBar.throttle = 0
|
||||
|
||||
self.statusBar:SetScript("OnUpdate", OnUpdateFunc)
|
||||
|
||||
local kill = self:RunHooksForWidget("OnTimerStart", self.statusBar, self)
|
||||
if (kill) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DF:CreateTimeBar(parent, texture, width, height, value, member, name)
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkBarNumber" .. DF.BarNameCounter
|
||||
DF.BarNameCounter = DF.BarNameCounter + 1
|
||||
|
||||
elseif (not parent) then
|
||||
return error("Details! FrameWork: parent not found.", 2)
|
||||
end
|
||||
|
||||
if (name:find("$parent")) then
|
||||
local parentName = DF.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
|
||||
local timeBar = {
|
||||
type = "timebar",
|
||||
dframework = true
|
||||
}
|
||||
|
||||
if (member) then
|
||||
parent[member] = timeBar
|
||||
end
|
||||
if (parent.dframework) then
|
||||
parent = parent.widget
|
||||
end
|
||||
|
||||
value = value or 0
|
||||
width = width or 150
|
||||
height = height or 14
|
||||
timeBar.locked = false
|
||||
|
||||
timeBar.statusBar = CreateFrame("statusbar", name, parent, "BackdropTemplate")
|
||||
timeBar.widget = timeBar.statusBar
|
||||
DF:Mixin(timeBar.statusBar, DF.WidgetFunctions)
|
||||
timeBar.statusBar.MyObject = timeBar
|
||||
timeBar.direction = "right"
|
||||
|
||||
if (not APITimeBarFunctions) then
|
||||
APITimeBarFunctions = true
|
||||
local idx = getmetatable(timeBar.statusBar).__index
|
||||
for funcName, funcAddress in pairs(idx) do
|
||||
if (not TimeBarMetaFunctions[funcName]) then
|
||||
TimeBarMetaFunctions[funcName] = function(object, ...)
|
||||
local x = loadstring("return _G['"..object.statusBar:GetName().."']:"..funcName.."(...)")
|
||||
return x(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--create widgets
|
||||
timeBar.statusBar:SetWidth(width)
|
||||
timeBar.statusBar:SetHeight(height)
|
||||
timeBar.statusBar:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
timeBar.statusBar:SetMinMaxValues(0, 100)
|
||||
timeBar.statusBar:SetValue(value or 100)
|
||||
timeBar.statusBar:EnableMouse(false)
|
||||
|
||||
timeBar.statusBar.backgroundTexture = timeBar.statusBar:CreateTexture(nil, "border")
|
||||
timeBar.statusBar.backgroundTexture:SetColorTexture(.1, .1, .1, .6)
|
||||
timeBar.statusBar.backgroundTexture:SetAllPoints()
|
||||
|
||||
timeBar.statusBar.barTexture = timeBar.statusBar:CreateTexture(nil, "artwork")
|
||||
timeBar.statusBar.barTexture:SetTexture(texture or [[Interface\WorldStateFrame\WORLDSTATEFINALSCORE-HIGHLIGHT]])
|
||||
timeBar.statusBar:SetStatusBarTexture(timeBar.statusBar.barTexture)
|
||||
|
||||
timeBar.statusBar.spark = timeBar.statusBar:CreateTexture(nil, "overlay", nil, 7)
|
||||
timeBar.statusBar.spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
timeBar.statusBar.spark:SetBlendMode("ADD")
|
||||
timeBar.statusBar.spark:Hide()
|
||||
|
||||
timeBar.statusBar.icon = timeBar.statusBar:CreateTexture(nil, "overlay", nil, 5)
|
||||
timeBar.statusBar.icon:SetPoint("left", timeBar.statusBar, "left", 2, 0)
|
||||
|
||||
timeBar.statusBar.leftText = timeBar.statusBar:CreateFontString("$parentLeftText", "overlay", "GameFontNormal", 4)
|
||||
timeBar.statusBar.leftText:SetPoint("left", timeBar.statusBar.icon, "right", 2, 0)
|
||||
|
||||
timeBar.statusBar.rightText = timeBar.statusBar:CreateFontString(nil, "overlay", "GameFontNormal", 4)
|
||||
timeBar.statusBar.rightText:SetPoint("right", timeBar.statusBar, "right", -2, 0)
|
||||
timeBar.statusBar.rightText:SetJustifyH("left")
|
||||
|
||||
--hooks
|
||||
timeBar.HookList = {
|
||||
OnEnter = {},
|
||||
OnLeave = {},
|
||||
OnHide = {},
|
||||
OnShow = {},
|
||||
OnMouseDown = {},
|
||||
OnMouseUp = {},
|
||||
OnTimerStart = {},
|
||||
OnTimerEnd = {},
|
||||
}
|
||||
|
||||
timeBar.statusBar:SetScript("OnEnter", OnEnterFunc)
|
||||
timeBar.statusBar:SetScript("OnLeave", OnLeaveFunc)
|
||||
timeBar.statusBar:SetScript("OnHide", OnHideFunc)
|
||||
timeBar.statusBar:SetScript("OnShow", OnShowFunc)
|
||||
timeBar.statusBar:SetScript("OnMouseDown", OnMouseDownFunc)
|
||||
timeBar.statusBar:SetScript("OnMouseUp", OnMouseUpFunc)
|
||||
|
||||
--set class
|
||||
setmetatable(timeBar, TimeBarMetaFunctions)
|
||||
|
||||
return timeBar
|
||||
end
|
||||
@@ -1,2 +0,0 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
|
||||
</Ui>
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
local DetailsFramework = _G["DetailsFramework"]
|
||||
if (not DetailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
local _
|
||||
|
||||
local DF = DetailsFramework
|
||||
|
||||
--backdrop namespace
|
||||
DF.BackdropUtil = {}
|
||||
|
||||
function DF.BackdropUtil:SetColorStripe(frame, index, backdrop, color1, color2)
|
||||
if (backdrop == nil or type(backdrop) == "table") then
|
||||
frame:SetBackdrop(backdrop and {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
end
|
||||
if (index % 2 == 0) then
|
||||
local r, g, b, a = DF:ParseColors(color1 or {.2, .2, .2, 0.5})
|
||||
frame:SetBackdropColor(r, g, b, a)
|
||||
else
|
||||
local r, g, b, a = DF:ParseColors(color2 or {.3, .3, .3, 0.5})
|
||||
frame:SetBackdropColor(r, g, b, a)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user