Major upgrade for alpha testers

This commit is contained in:
Tercio Jose
2023-11-30 16:13:14 -03:00
parent 319fe4c84e
commit 0ff046b500
24 changed files with 2616 additions and 1399 deletions
+5
View File
@@ -855,6 +855,11 @@ end
debuffTrackedAuraScrollBox:SetPoint("topleft", auraPanel_Auto, "topleft", 16 +(scrollWidth * 2) + xLocation, y)
buffTrackedAuraScrollBox:SetPoint("topleft", auraPanel_Auto, "topleft", 24 +(scrollWidth * 3) + xLocation, y)
buffTrackedAuraScrollBox:GetTitleFontString():SetText(newAuraPanel.LocTexts.BUFFS_TRACKED)
debuffTrackedAuraScrollBox:GetTitleFontString():SetText(newAuraPanel.LocTexts.DEBUFFS_TRACKED)
buffIgnoredAuraScrollBox:GetTitleFontString():SetText(newAuraPanel.LocTexts.BUFFS_IGNORED)
debuffIgnoredAuraScrollBox:GetTitleFontString():SetText(newAuraPanel.LocTexts.DEBUFFS_IGNORED)
newAuraPanel.buff_ignored = buffIgnoredAuraScrollBox
newAuraPanel.debuff_ignored = debuffIgnoredAuraScrollBox
newAuraPanel.buff_tracked = buffTrackedAuraScrollBox
+963 -1031
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -45,6 +45,7 @@
---@class detailsframework
---@field dversion number
---@field internalFunctions table
---@field OptionsFunctions df_optionsmixin
---@field GlobalWidgetControlNames table
---@field RoundedCornerPanelMixin df_roundedcornermixin
@@ -56,7 +57,7 @@
---@field EditorMixin df_editormixin
---@field ClassCache {ID:number, Name:string, FileString:string, Texture:string, TexCoord:number[]}[] only available after calling GetClassList()
---@field Math df_math
---@field FontOutlineFlags {key1:outline, key2:string}[]
---@field FontOutlineFlags table<outline, boolean>
---@field table df_table_functions
---@field AnchorPoints string[]
---@field ClassFileNameToIndex table<string, number> engClass -> classIndex
@@ -102,7 +103,7 @@
---@field CommaValue fun(self:table, value:number) : string convert a number to a string with commas, e.g. 1000000 -> 1,000,000
---@field SplitTextInLines fun(self:table, text:string) : string[] split a text into lines
---@field UnitGroupRolesAssigned fun(unitId: unit, bUseSupport:boolean, specId: specializationid) : string there's no self here
---@field SetAnchor fun(self:table, widget:uiobject, anchorTable:df_anchor, anchorTo:uiobject)
---@field SetAnchor fun(self:table, widget:uiobject, anchorTable:df_anchor, anchorTo:uiobject?) only adjust the anchors of a widget, does not save values
---@field AddTextureToText fun(text:string, textureInfo:table, bAddSpace:boolean?, bAddAfterText:boolean) : string textureInfo is a table with .texture .width .height .coords{left, right, top, bottom}
---@field CreateTextureInfo fun(texture:atlasname|texturepath|textureid, width:number?, height:number?, left:number?, right:number?, top:number?, bottom:number?, imageWidthnumber?, imageHeightnumber?) : table
---@field ApplyStandardBackdrop fun(self:table, frame:frame, bUseSolidColor:boolean?, alphaScale:number?)
@@ -132,8 +133,10 @@
---@field CreateAuraScrollBox fun(self:table, parent:frame, name:string?, data:table?, onRemoveCallback:function?, options:table?) : df_aurascrollbox
---@field CreateGridScrollBox fun(self:table, parent:frame, name:string?, refreshFunc:function, data:table?, createColumnFrameFunc:function, options:table?) : df_gridscrollbox
---@field CreateCanvasScrollBox fun(self:table, parent:frame, child:frame?, name:string?, options:table?) : df_canvasscrollbox
---@field CreateTabContainer fun(self:table, parent:frame, title:string, frameName:string, tabList:df_tabinfotable[], optionsTable:table?, hookList:table?, languageInfo:table?) : df_tabcontainer
---@field GetSizeFromPercent fun(self:table, uiObject:uiobject, percent:number) : number get the min size of a uiObject and multiply it by the percent passed
---@field BuildMenu fun(self:table, parent:frame, menuOptions:df_menu_table[], xOffset:number?, yOffset:number?, height:number?, useColon:boolean?, textTemplate:table?, dropdownTemplate:table?, switchTemplate:table?, switchIsCheckbox:boolean?, sliderTemplate:table?, buttonTemplate:table?, valueChangeHook:function?)
---@field BuildMenuVolatile fun(self:table, parent:frame, menuOptions:df_menu_table[], xOffset:number?, yOffset:number?, height:number?, useColon:boolean?, textTemplate:table?, dropdownTemplate:table?, switchTemplate:table?, switchIsCheckbox:boolean?, sliderTemplate:table?, buttonTemplate:table?, valueChangeHook:function?)
---@field
---@field
+7 -9
View File
@@ -986,16 +986,13 @@ function DetailsFrameworkDropDownOnHide(self)
object:Close()
end
local iconSizeTable = {16, 16}
function DF:BuildDropDownFontList(onClick, icon, iconTexcoord, iconSize)
local fontTable = {}
if (type(iconSize) ~= "table") then
iconSize = {iconSize or 16, iconSize or 16}
end
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
for name, fontPath in pairs(SharedMedia:HashTable("font")) do
fontTable[#fontTable+1] = {value = name, label = name, onclick = onClick, icon = icon, iconsize = iconSize, texcoord = iconTexcoord, font = fontPath, descfont = "abcdefg ABCDEFG"}
fontTable[#fontTable+1] = {value = name, label = name, onclick = onClick, icon = icon, iconsize = iconSizeTable, texcoord = iconTexcoord, font = fontPath, descfont = "abcdefg ABCDEFG"}
end
table.sort(fontTable, function(t1, t2) return t1.label < t2.label end)
@@ -1141,11 +1138,12 @@ function DF:CreateOutlineListGenerator(callback)
local newGenerator = function()
local dropdownOptions = {}
for i, outlineInfo in ipairs(DF.FontOutlineFlags) do
local outlineName, outlineLoc = unpack(outlineInfo)
for index, outlineInfo in pairs(DF.FontOutlineFlags) do
local outlineValue = outlineInfo[1]
local outlineName = outlineInfo[2]
table.insert(dropdownOptions, {
label = outlineLoc,
value = outlineName,
label = outlineName,
value = outlineValue,
onclick = callback
})
end
+657 -100
View File
@@ -14,7 +14,7 @@ local _
--[=[
file description: this file has the code for the object editor
the object editor itself is a frame and has a scrollframe as canvas showing another frame where there's the options for the editing object
--]=]
@@ -22,10 +22,10 @@ local _
--the mapTable is a table with the attribute name as a key, and the value is the profile key. For example, {["size"] = "text_size"} means profileTable["text_size"] = 10.
---@class df_editor_attribute
---@field name string
---@field label string
---@field name string?
---@field label string?
---@field widget string
---@field default any
---@field default any?
---@field minvalue number?
---@field maxvalue number?
---@field step number?
@@ -55,12 +55,15 @@ local attributes = {
name = "font",
label = "Font",
widget = "fontdropdown",
setter = function(widget, value) widget:SetFont(value, select(2, widget:GetFont())) end
setter = function(widget, value)
local font = LibStub:GetLibrary("LibSharedMedia-3.0"):Fetch("font", value)
widget:SetFont(font, select(2, widget:GetFont()))
end
},
{
name = "color",
label = "Color",
widget = "colordropdown",
widget = "color",
setter = function(widget, value) widget:SetTextColor(unpack(value)) end
},
{
@@ -69,6 +72,7 @@ local attributes = {
widget = "range",
setter = function(widget, value) widget:SetAlpha(value) end
},
{widget = "blank"},
{
name = "shadow",
label = "Draw Shadow",
@@ -78,7 +82,7 @@ local attributes = {
{
name = "shadowcolor",
label = "Shadow Color",
widget = "colordropdown",
widget = "color",
setter = function(widget, value) widget:SetShadowColor(unpack(value)) end
},
{
@@ -103,6 +107,7 @@ local attributes = {
widget = "outlinedropdown",
setter = function(widget, value) widget:SetFont(widget:GetFont(), select(2, widget:GetFont()), value) end
},
{widget = "blank"},
{
name = "anchor",
label = "Anchor",
@@ -113,16 +118,16 @@ local attributes = {
name = "anchoroffsetx",
label = "Anchor X Offset",
widget = "range",
minvalue = -20,
maxvalue = 20,
minvalue = -100,
maxvalue = 100,
setter = function(widget, value) detailsFramework:SetAnchor(widget, value, widget:GetParent()) end
},
{
name = "anchoroffsety",
label = "Anchor Y Offset",
widget = "range",
minvalue = -20,
maxvalue = 20,
minvalue = -100,
maxvalue = 100,
setter = function(widget, value) detailsFramework:SetAnchor(widget, value, widget:GetParent()) end
},
{
@@ -134,56 +139,59 @@ local attributes = {
maxvalue = math.pi*2,
setter = function(widget, value) widget:SetRotation(value) end
},
{
name = "scale",
label = "Scale",
widget = "range",
usedecimals = true,
minvalue = 0.65,
maxvalue = 2.5,
setter = function(widget, value) widget:SetScale(value) end
},
}
}
local profileTable = {
spellname_text_size = 10,
spellname_text_font = "Arial Narrow",
spellname_text_color = {1, 1, 1, 1},
spellname_text_outline = "NONE",
spellname_text_shadow_color = {0, 0, 0, 1},
spellname_text_shadow_color_offset = {1, -1},
spellname_text_anchor = {side = 9, x = 0, y = 0},
}
--create a map table for the profile table
local mapTable = {
text = "text test",
size = "spellname_text_size",
font = "spellname_text_font",
color = "spellname_text_color",
outline = "spellname_text_outline",
shadowcolor = "spellname_text_shadow_color",
shadowoffsetx = "spellname_text_shadow_color_offset[1]",
shadowoffsety = "spellname_text_shadow_color_offset[2]",
anchor = "spellname_text_anchor.side",
anchoroffsetx = "spellname_text_anchor.x",
anchoroffsety = "spellname_text_anchor.y",
}
local table_path = {
shadowWidth = "text_settings[1].width",
shadowHeight = "text_settings[1].height",
shadowEnabled = "text_settings.settings.enabled",
text = "text_settings.settings.text.current_text",
}
local text_settings = {
shadowWidth = {{width = 100}},
shadowHeight = {{height = 100}},
shadowEnabled = {settings = {enabled = true}},
text = {settings = {text = {current_text = "hellow world"}}},
}
---@class df_editormixin : table
---@field GetAllRegisteredObjects fun(self:df_editor):df_editor_objectinfo[]
---@field GetEditingObject fun(self:df_editor):uiobject
---@field GetEditingOptions fun(self:df_editor):df_editobjectoptions
---@field GetExtraOptions fun(self:df_editor):table
---@field GetEditingProfile fun(self:df_editor):table, table
---@field GetOnEditCallback fun(self:df_editor):function
---@field GetOptionsFrame fun(self:df_editor):frame
---@field GetCanvasScrollBox fun(self:df_editor):df_canvasscrollbox
---@field EditObject fun(self:df_editor, object:uiobject, profileTable:table, profileKeyMap:table, callback:function)
---@field GetObjectSelector fun(self:df_editor):df_scrollbox
---@field EditObject fun(self:df_editor, object:uiobject, profileTable:table, profileKeyMap:table, extraOptions:table?, callback:function?, options:df_editobjectoptions?)
---@field PrepareObjectForEditing fun(self:df_editor)
---@field CreateMoverGuideLines fun(self:df_editor)
---@field GetOverTheTopFrame fun(self:df_editor):frame
---@field GetMoverFrame fun(self:df_editor):frame
---@field StartObjectMovement fun(self:df_editor, anchorSettings:df_anchor)
---@field StopObjectMovement fun(self:df_editor)
---@class df_editobjectoptions : table
---@field use_colon boolean if true a colon is shown after the option name
---@field can_move boolean if true the object can be moved
---@field use_guide_lines boolean if true guide lines are shown when the object is being moved
---@type df_editobjectoptions
local editObjectDefaultOptions = {
use_colon = true,
can_move = true,
use_guide_lines = true,
}
local getParentTable = function(profileTable, profileKey)
local parentPath
if (profileKey:match("%]$")) then
parentPath = profileKey:gsub("%s*%[.*%]%s*$", "")
else
parentPath = profileKey:gsub("%.[^.]*$", "")
end
local parentTable = detailsFramework.table.getfrompath(profileTable, parentPath)
return parentTable
end
detailsFramework.EditorMixin = {
---@param self df_editor
@@ -191,6 +199,18 @@ detailsFramework.EditorMixin = {
return self.editingObject
end,
---@param self df_editor
---@return df_editobjectoptions
GetEditingOptions = function(self)
return self.editingOptions
end,
---@param self df_editor
---@return table
GetExtraOptions = function(self)
return self.editingExtraOptions
end,
---@param self df_editor
---@return table, table
GetEditingProfile = function(self)
@@ -207,28 +227,117 @@ detailsFramework.EditorMixin = {
return self.optionsFrame
end,
GetOverTheTopFrame = function(self)
return self.overTheTopFrame
end,
GetMoverFrame = function(self)
return self.moverFrame
end,
GetCanvasScrollBox = function(self)
return self.canvasScrollBox
end,
---@param self df_editor
---@param object uiobject
---@param profileTable table
---@param profileKeyMap table
---@param callback function calls when an attribute is changed with the payload: editingObject, optionName, newValue, profileTable, profileKey
EditObject = function(self, object, profileTable, profileKeyMap, callback)
assert(type(object) == "table", "EditObject(object) expects an UIObject on first parameter.")
assert(type(profileTable) == "table", "EditObject(object) expects a table on second parameter.")
assert(object.GetObjectType, "EditObject(object) expects an UIObject on first parameter.")
GetObjectSelector = function(self)
return self.objectSelector
end,
EditObjectById = function(self, id)
---@type df_editor_objectinfo
local objectRegistered = self:GetObjectById(id)
assert(type(objectRegistered) == "table", "EditObjectById() object not found.")
self:EditObject(objectRegistered)
end,
EditObjectByIndex = function(self, index)
---@type df_editor_objectinfo
local objectRegistered = self:GetObjectByIndex(index)
assert(type(objectRegistered) == "table", "EditObjectById() object not found.")
self:EditObject(objectRegistered)
end,
---@param self df_editor
---@param registeredObject df_editor_objectinfo
EditObject = function(self, registeredObject)
--clear previous values
self.editingObject = nil
self.editingProfileMap = nil
self.editingProfileTable = nil
self.editingOptions = nil
self.editingExtraOptions = nil
self.onEditCallback = nil
local object = registeredObject.object
local profileTable = registeredObject.profiletable
local profileKeyMap = registeredObject.profilekeymap
local extraOptions = registeredObject.extraoptions
local callback = registeredObject.callback
local options = registeredObject.options
--as there's no other place which this members are set, there is no need to create setter functions
self.editingObject = object
self.editingProfileMap = profileKeyMap
self.editingProfileTable = profileTable
self.onEditCallback = callback
self.editingOptions = options
self.editingExtraOptions = extraOptions
if (type(callback) == "function") then
self.onEditCallback = callback
end
self:PrepareObjectForEditing()
end,
---@param self df_editor
CreateMoverGuideLines = function(self)
local overTheTopFrame = self:GetOverTheTopFrame()
local moverFrame = self:GetMoverFrame()
self.moverGuideLines = {
left = overTheTopFrame:CreateTexture(nil, "overlay"),
right = overTheTopFrame:CreateTexture(nil, "overlay"),
top = overTheTopFrame:CreateTexture(nil, "overlay"),
bottom = overTheTopFrame:CreateTexture(nil, "overlay"),
}
for side, texture in pairs(self.moverGuideLines) do
texture:SetColorTexture(.8, .8, .8, 0.1)
texture:SetSize(1, 1)
texture:SetDrawLayer("overlay", 7)
texture:Hide()
if (side == "left" or side == "right") then
texture:SetHeight(1)
texture:SetWidth(GetScreenWidth())
else
texture:SetWidth(1)
texture:SetHeight(GetScreenHeight())
end
end
end,
UpdateGuideLinesAnchors = function(self)
local object = self:GetEditingObject()
for side, texture in pairs(self.moverGuideLines) do
texture:ClearAllPoints()
if (side == "left" or side == "right") then
if (side == "left") then
texture:SetPoint("right", object, "left", -2, 0)
else
texture:SetPoint("left", object, "right", 2, 0)
end
else
if (side == "top") then
texture:SetPoint("bottom", object, "top", 0, 2)
else
texture:SetPoint("top", object, "bottom", 0, -2)
end
end
end
end,
PrepareObjectForEditing = function(self)
--get the object and its profile table with the current values
local object = self:GetEditingObject()
@@ -243,56 +352,135 @@ detailsFramework.EditorMixin = {
local objectType = object:GetObjectType()
local attributeList
--get options and extra options
local editingOptions = self:GetEditingOptions()
local extraOptions = self:GetExtraOptions()
--get the attribute list for the object type
if (objectType == "FontString") then
---@cast object fontstring
attributeList = attributes[objectType]
end
--if there's extra options, add the attributeList to a new table and right after the extra options
if (extraOptions and #extraOptions > 0) then
local attributeListWithExtraOptions = {}
for i = 1, #attributeList do
attributeListWithExtraOptions[#attributeListWithExtraOptions+1] = attributeList[i]
end
attributeListWithExtraOptions[#attributeListWithExtraOptions+1] = {widget = "blank", default = true}
for i = 1, #extraOptions do
attributeListWithExtraOptions[#attributeListWithExtraOptions+1] = extraOptions[i]
end
attributeList = attributeListWithExtraOptions
end
local anchorSettings
--table to use on DF:BuildMenu()
local menuOptions = {}
for i = 1, #attributeList do
local option = attributeList[i]
--get the key to be used on profile table
local profileKey = profileMap[option.name]
local value
--if the key contains a dot or a bracket, it means it's a table path, example: "text_settings[1].width"
if (profileKey and (profileKey:match("%.") or profileKey:match("%["))) then
value = detailsFramework.table.getfrompath(profileTable, profileKey)
if (option.widget == "blank") then
menuOptions[#menuOptions+1] = {type = "blank"}
else
value = profileTable[profileKey]
end
--get the key to be used on profile table
local profileKey = profileMap[option.name]
local value
--if no value is found, attempt to get a default
value = value or option.default
--if the key contains a dot or a bracket, it means it's a table path, example: "text_settings[1].width"
if (profileKey and (profileKey:match("%.") or profileKey:match("%["))) then
value = detailsFramework.table.getfrompath(profileTable, profileKey)
else
value = profileTable[profileKey]
end
if (value) then
menuOptions[#menuOptions+1] = {
type = option.widget,
name = option.label,
get = function() return value end,
set = function(widget, fixedValue, newValue)
if (profileKey and (profileKey:match("%.") or profileKey:match("%["))) then
detailsFramework.table.setfrompath(profileTable, profileKey, value)
else
profileTable[profileKey] = value
end
--if no value is found, attempt to get a default
if (type(value) == "nil") then
value = option.default
end
if (self:GetOnEditCallback()) then
self:GetOnEditCallback()(object, option.name, newValue, profileTable, profileKey)
end
local bHasValue = type(value) ~= "nil"
if (option.name == "anchor" or option.name == "anchoroffsetx" or option.name == "anchoroffsety") then
local anchorTable = detailsFramework.table.getfrompath(profileTable, profileKey:gsub("%.[^.]*$", ""))
option.setter(object, anchorTable)
else
option.setter(object, newValue)
end
end,
min = option.minvalue,
max = option.maxvalue,
step = option.step,
usedecimals = option.usedecimals,
}
local minValue = option.minvalue
local maxValue = option.maxvalue
if (option.name == "anchoroffsetx") then
minValue = -object:GetParent():GetWidth()/2
maxValue = object:GetParent():GetWidth()/2
elseif (option.name == "anchoroffsety") then
minValue = -object:GetParent():GetHeight()/2
maxValue = object:GetParent():GetHeight()/2
end
if (option.name == "classcolor") then print("", value) end
if (bHasValue) then
if (option.name == "classcolor") then print("HERE", value) end
local parentTable = getParentTable(profileTable, profileKey)
if (option.name == "anchor" or option.name == "anchoroffsetx" or option.name == "anchoroffsety") then
anchorSettings = parentTable
end
menuOptions[#menuOptions+1] = {
type = option.widget,
name = option.label,
get = function() return value end,
set = function(widget, fixedValue, newValue, ...)
--color is a table with 4 indexes for each color plus alpha
if (option.widget == "color") then
--calor callback sends the red color in the fixedParameter slot
local r, g, b, alpha = fixedValue, newValue, ...
--need to use the same table from the profile table
parentTable[1] = r
parentTable[2] = g
parentTable[3] = b
parentTable[4] = alpha
newValue = parentTable
else
detailsFramework.table.setfrompath(profileTable, profileKey, newValue)
end
if (self:GetOnEditCallback()) then
self:GetOnEditCallback()(object, option.name, newValue, profileTable, profileKey)
end
--update the widget visual
--anchoring uses SetAnchor() which require the anchorTable to be passed
if (option.name == "anchor" or option.name == "anchoroffsetx" or option.name == "anchoroffsety") then
anchorSettings = parentTable
if (option.name == "anchor") then
anchorSettings.x = 0
anchorSettings.y = 0
end
self:StopObjectMovement()
option.setter(object, parentTable)
if (editingOptions.can_move) then
self:StartObjectMovement(anchorSettings)
end
else
option.setter(object, newValue)
end
end,
min = minValue,
max = maxValue,
step = option.step,
usedecimals = option.usedecimals,
id = option.name,
}
end
end
end
@@ -303,7 +491,9 @@ detailsFramework.EditorMixin = {
local optionsFrame = self:GetOptionsFrame()
local canvasScrollBox = self:GetCanvasScrollBox()
local bUseColon = true
local bUseColon = editingOptions.use_colon
local bSwitchIsCheckbox = true
local maxHeight = 5000
@@ -318,25 +508,361 @@ detailsFramework.EditorMixin = {
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
detailsFramework:BuildMenu(optionsFrame, menuOptions, 0, -2, maxHeight, bUseColon, options_text_template, options_dropdown_template, options_switch_template, bSwitchIsCheckbox, options_slider_template, options_button_template)
detailsFramework:BuildMenuVolatile(optionsFrame, menuOptions, 0, -2, maxHeight, bUseColon, options_text_template, options_dropdown_template, options_switch_template, bSwitchIsCheckbox, options_slider_template, options_button_template)
if (editingOptions.can_move) then
self:StartObjectMovement(anchorSettings)
end
end,
---@param self df_editor
---@param anchorSettings df_anchor
StartObjectMovement = function(self, anchorSettings)
local object = self:GetEditingObject()
local moverFrame = self:GetMoverFrame()
--self:UpdateGuideLinesAnchors()
--update guidelines
if (self:GetEditingOptions().use_guide_lines) then
--show all four guidelines
for side, texture in pairs(self.moverGuideLines) do
texture:Show()
end
end
local optionsFrame = self:GetOptionsFrame()
moverFrame:EnableMouse(true)
moverFrame:SetMovable(true)
moverFrame:ClearAllPoints()
moverFrame:Show()
--update the mover frame size to match the object size
if (object:GetObjectType() == "FontString") then
---@cast object fontstring
local width = object:GetStringWidth()
local height = object:GetStringHeight()
moverFrame:SetSize(width, height)
else
local width, height = object:GetSize()
moverFrame:SetSize(width, height)
end
for i = 1, object:GetNumPoints() do
local point, relativeTo, relativePoint, x, y = object:GetPoint(i)
moverFrame:SetPoint(point, relativeTo, relativePoint, x, y)
end
local currentPosX, currentPosY
moverFrame:SetScript("OnMouseDown", function()
object:ClearAllPoints()
object:SetPoint("topleft", moverFrame, "topleft", 0, 0)
currentPosX, currentPosY = moverFrame:GetCenter()
moverFrame:SetBackdropBorderColor(1, 1, 0, 0)
for i = 1, object:GetNumPoints() do
local point, relativeTo, relativePoint, x, y = object:GetPoint(i)
moverFrame:SetPoint(point, relativeTo, relativePoint, x, y)
end
moverFrame:StartMoving()
moverFrame.bIsMoving = true
end)
moverFrame:SetScript("OnMouseUp", function()
moverFrame:StopMovingOrSizing()
moverFrame.bIsMoving = false
object:ClearAllPoints()
detailsFramework:SetAnchor(object, anchorSettings, object:GetParent())
moverFrame:ClearAllPoints()
for i = 1, object:GetNumPoints() do
local point, relativeTo, relativePoint, x, y = object:GetPoint(i)
moverFrame:SetPoint(point, relativeTo, relativePoint, x, y)
end
end)
--detailsFramework:SetAnchor(moverFrame, anchorSettings)
--detailsFramework:SetAnchor(object, anchorSettings, moverFrame)
moverFrame:SetScript("OnUpdate", function()
--if the object isn't moving, make the mover follow the object position
if (moverFrame.bIsMoving) then
object:ClearAllPoints()
object:SetPoint("topleft", moverFrame, "topleft", 0, 0)
--if the object is moving, check if the moverFrame has moved
local newPosX, newPosY = moverFrame:GetCenter()
--did the frame moved?
if (newPosX ~= currentPosX) then
local xOffset = newPosX - currentPosX
anchorSettings.x = anchorSettings.x + xOffset
local anchorXSlider = optionsFrame:GetWidgetById("anchoroffsetx")
anchorXSlider:SetValueNoCallback(anchorSettings.x)
end
if (newPosY ~= currentPosY) then
local yOffset = newPosY - currentPosY
anchorSettings.y = anchorSettings.y + yOffset
local anchorYSlider = optionsFrame:GetWidgetById("anchoroffsety")
anchorYSlider:SetValueNoCallback(anchorSettings.y)
end
currentPosX, currentPosY = newPosX, newPosY
end
--[=[
--update the mover frame size to match the object size
if (object:GetObjectType() == "FontString") then
---@cast object fontstring
local width = object:GetStringWidth()
local height = object:GetStringHeight()
moverFrame:SetSize(width, height)
else
local width, height = object:GetSize()
moverFrame:SetSize(width, height)
end
--]=]
end)
end,
---@param self df_editor
StopObjectMovement = function(self)
local moverFrame = self:GetMoverFrame()
moverFrame:EnableMouse(false)
moverFrame:SetScript("OnUpdate", nil)
--hide all four guidelines
for side, texture in pairs(self.moverGuideLines) do
texture:Hide()
end
moverFrame:Hide()
end,
RegisterObject = function(self, object, localizedLabel, id, profileTable, profileKeyMap, extraOptions, callback, options)
assert(type(object) == "table", "RegisterObjectToEdit() expects an UIObject on #1 parameter.")
assert(object.GetObjectType, "RegisterObjectToEdit() expects an UIObject on #1 parameter.")
assert(type(profileTable) == "table", "RegisterObjectToEdit() expects a table on #4 parameter.")
assert(type(id) ~= "nil" and type(id) ~= "boolean", "RegisterObjectToEdit() expects an ID on parameter #3.")
assert(type(callback) == "function" or callback == nil, "RegisterObjectToEdit() expects a function or nil as the #7 parameter.")
local registeredObjects = self:GetAllRegisteredObjects()
--is object already registered?
for i = 1, #registeredObjects do
local objectRegistered = registeredObjects[i]
if (objectRegistered.object == object) then
error("RegisterObjectToEdit() object already registered.")
end
end
--deploy the options table
options = type(options) == "table" and options or {}
detailsFramework.table.deploy(options, editObjectDefaultOptions)
localizedLabel = type(localizedLabel) == "string" and localizedLabel or "invalid label"
---@type df_editor_objectinfo
local objectRegistered = {
object = object,
label = localizedLabel,
id = id,
profiletable = profileTable,
profilekeymap = profileKeyMap,
extraoptions = extraOptions or {},
callback = callback,
options = options,
}
registeredObjects[#registeredObjects+1] = objectRegistered
self.registeredObjectsByID[id] = objectRegistered
local objectSelector = self:GetObjectSelector()
objectSelector:RefreshMe()
--what to do after an object is registered?
return objectRegistered
end,
UnregisterObject = function(self, object)
local registeredObjects = self:GetAllRegisteredObjects()
for i = 1, #registeredObjects do
local objectRegistered = registeredObjects[i]
if (objectRegistered.object == object) then
self.registeredObjectsByID[objectRegistered.id] = nil
table.remove(registeredObjects, i)
break
end
end
local objectSelector = self:GetObjectSelector()
objectSelector:RefreshMe()
--stop editing the object
end,
---@param self df_editor
---@return df_editor_objectinfo[]
GetAllRegisteredObjects = function(self)
return self.registeredObjects
end,
---@param self df_editor
---@return df_editor_objectinfo?
GetObjectByRef = function(self, object)
local registeredObjects = self:GetAllRegisteredObjects()
for i = 1, #registeredObjects do
local objectRegistered = registeredObjects[i]
if (objectRegistered.object == object) then
return objectRegistered
end
end
end,
GetObjectByIndex = function(self, index)
local registeredObjects = self:GetAllRegisteredObjects()
return registeredObjects[index]
end,
GetObjectById = function(self, id)
return self.registeredObjectsByID[id]
end,
CreateObjectSelectionList = function(self, scroll_width, scroll_height, scroll_lines, scroll_line_height)
local editorFrame = self
local refreshFunc = function(self, data, offset, totalLines) --~refresh
for i = 1, totalLines do
local index = i + offset
---@type df_editor_objectinfo
local objectRegistered = data[index]
if (objectRegistered) then
local line = self:GetLine(i)
line.index = index
if (objectRegistered.object:GetObjectType() == "Texture") then
line.Icon:SetTexture([[Interface\AnimCreate\AnimCreateIcons]])
line.Icon:SetTexCoord(1/4, 2/4, 1/4, 2/4)
elseif (objectRegistered.object:GetObjectType() == "Texture") then
line.Icon:SetTexture([[Interface\AnimCreate\AnimCreateIcons]])
line.Icon:SetTexCoord(2/4, 3/4, 0, 1/4)
end
line.Label:SetText(objectRegistered.label)
end
end
end
local createLineFunc = function(self, index) -- ~createline --~line
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(scroll_line_height+1)) - 1)
line:SetSize(scroll_width - 2, scroll_line_height)
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
if (index % 2 == 0) then
line:SetBackdropColor(.1, .1, .1, .1)
else
line:SetBackdropColor(.1, .1, .1, .4)
end
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
--line:SetScript("OnEnter", lineOnEnter)
--line:SetScript("OnLeave", lineOnLeave)
line:SetScript("OnClick", function(self)
local objectRegistered = editorFrame:GetObjectByIndex(self.index)
editorFrame:EditObject(objectRegistered)
end)
--icon
local objectIcon = line:CreateTexture("$parentIcon", "overlay")
objectIcon:SetSize(scroll_line_height - 2, scroll_line_height - 2)
--object label
local objectLabel = line:CreateFontString("$parentLabel", "overlay", "GameFontNormal")
objectIcon:SetPoint("left", line, "left", 2, 0)
objectLabel:SetPoint("left", objectIcon, "right", 2, 0)
line.Icon = objectIcon
line.Label = objectLabel
return line
end
local selectObjectScrollBox = detailsFramework:CreateScrollBox(self:GetParent(), "$parentSelectObjectScrollBox", refreshFunc, editorFrame:GetAllRegisteredObjects(), scroll_width, scroll_height, scroll_lines, scroll_line_height)
detailsFramework:ReskinSlider(selectObjectScrollBox)
function selectObjectScrollBox:RefreshMe()
selectObjectScrollBox:SetData(editorFrame:GetAllRegisteredObjects())
selectObjectScrollBox:Refresh()
end
--create lines
for i = 1, scroll_lines do
selectObjectScrollBox:CreateLine(createLineFunc)
end
return selectObjectScrollBox
end,
}
---@class df_editor_defaultoptions : table
---@field width number
---@field height number
---@field create_object_list boolean
---@field object_list_width number
---@field object_list_height number
---@field object_list_lines number
---@field object_list_line_height number
---@class df_editor_defaultoptions
local editorDefaultOptions = {
width = 400,
height = 600,
create_object_list = true,
object_list_width = 200,
object_list_height = 420,
object_list_lines = 20,
object_list_line_height = 20,
}
---@class df_editor : frame, df_optionsmixin, df_editormixin
---@field options table
---@field registeredObjects df_editor_objectinfo[]
---@field registeredObjectsByID table<any, df_editor_objectinfo>
---@field editingObject uiobject
---@field editingProfileTable table
---@field editingProfileMap table
---@field editingOptions df_editobjectoptions
---@field editingExtraOptions table
---@field moverGuideLines table<string, texture>
---@field onEditCallback function
---@field optionsFrame frame
---@field overTheTopFrame frame
---@field objectSelector df_scrollbox
---@field moverFrame frame
---@field canvasScrollBox df_canvasscrollbox
---@class df_editor_objectinfo : table
---@field object uiobject
---@field label string
---@field id any
---@field profiletable table
---@field profilekeymap table
---@field extraoptions table
---@field callback function
---@field options df_editobjectoptions
function detailsFramework:CreateEditor(parent, name, options)
name = name or ("DetailsFrameworkEditor" .. math.random(100000, 10000000))
local editorFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
@@ -344,10 +870,25 @@ function detailsFramework:CreateEditor(parent, name, options)
detailsFramework:Mixin(editorFrame, detailsFramework.EditorMixin)
detailsFramework:Mixin(editorFrame, detailsFramework.OptionsFunctions)
editorFrame.registeredObjects = {}
editorFrame.registeredObjectsByID = {}
editorFrame:BuildOptionsTable(editorDefaultOptions, options)
editorFrame:SetSize(editorFrame.options.width, editorFrame.options.height)
if (editorFrame.options.create_object_list) then
local scrollWidth = editorFrame.options.object_list_width
local scrollHeight = editorFrame.options.object_list_height
local scrollLinesAmount = editorFrame.options.object_list_lines
local scrollLineHeight = editorFrame.options.object_list_line_height
local objectSelector = editorFrame:CreateObjectSelectionList(scrollWidth, scrollHeight, scrollLinesAmount, scrollLineHeight)
objectSelector:SetPoint("topleft", editorFrame, "topright", 2, 0)
editorFrame.objectSelector = objectSelector
objectSelector:RefreshMe()
end
--options frame is the frame that holds the options for the editing object, it is used as the parent frame for BuildMenuVolatile()
local optionsFrame = CreateFrame("frame", name .. "OptionsFrame", editorFrame, "BackdropTemplate")
optionsFrame:SetSize(editorFrame.options.width, 5000)
@@ -355,6 +896,22 @@ function detailsFramework:CreateEditor(parent, name, options)
local canvasFrame = detailsFramework:CreateCanvasScrollBox(editorFrame, optionsFrame, name .. "CanvasScrollBox")
canvasFrame:SetAllPoints()
--over the top frame is a frame that is always on top of everything else
local OTTFrame = CreateFrame("frame", "$parentOTTFrame", UIParent)
OTTFrame:SetFrameStrata("TOOLTIP")
editorFrame.overTheTopFrame = OTTFrame
--frame that is used to move the object
local moverFrame = CreateFrame("frame", "$parentMoverFrame", OTTFrame, "BackdropTemplate")
moverFrame:SetClampedToScreen(true)
moverFrame:SetBackdrop({
edgeFile = "Interface\\Buttons\\WHITE8x8",
edgeSize = 1,
})
editorFrame.moverFrame = moverFrame
editorFrame:CreateMoverGuideLines()
editorFrame.optionsFrame = optionsFrame
editorFrame.canvasScrollBox = canvasFrame
+663
View File
@@ -0,0 +1,663 @@
---@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_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
---@field horizontal_border_size_offset number?
---@class df_roundedpanel_preset : table, df_roundedpanel_options
---@field border_color any
---@field color any
---@field roundness number
---@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)
---@field GetMaxFrameLevel fun(self:df_roundedpanel) : number --return the max frame level of the frame and its children
---@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 bIsTitleBar boolean
---@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,
---get the highest frame level of the rounded panel and its children
---@param self df_roundedpanel
---@return framelevel
GetMaxFrameLevel = function(self)
---@type framelevel
local maxFrameLevel = 0
local children = {self:GetChildren()}
for i = 1, #children do
local thisChild = children[i]
---@cast thisChild frame
if (thisChild:GetFrameLevel() > maxFrameLevel) then
maxFrameLevel = thisChild:GetFrameLevel()
end
end
return maxFrameLevel
end,
---create a frame placed at the top side of the rounded panel, this frame has a member called 'Text' which is a fontstring for the title
---@param self df_roundedpanel
---@return df_roundedpanel
CreateTitleBar = function(self)
---@type df_roundedpanel
local titleBar = detailsFramework:CreateRoundedPanel(self, "$parentTitleBar", {width = self.options.width - 6, height = 16})
titleBar:SetPoint("top", self, "top", 0, -4)
titleBar:SetRoundness(5)
titleBar:SetFrameLevel(9500)
titleBar.bIsTitleBar = true
self.TitleBar = titleBar
self.bHasTitleBar = true
local textFontString = titleBar:CreateFontString("$parentText", "overlay", "GameFontNormal")
textFontString:SetPoint("center", titleBar, "center", 0, 0)
titleBar.Text = textFontString
local closeButton = detailsFramework:CreateCloseButton(titleBar, "$parentCloseButton")
closeButton:SetPoint("right", titleBar, "right", -3, 0)
closeButton:SetSize(10, 10)
closeButton:SetAlpha(0.3)
closeButton:SetScript("OnClick", function(self)
self:GetParent():GetParent():Hide()
end)
detailsFramework:SetButtonTexture(closeButton, "common-search-clearbutton")
return titleBar
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 - 2), 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-2, newCornerSize+2)
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 + (self.options.horizontal_border_size_offset or 0), 1)
self.BorderEdgeTextures["Bottom"]:SetSize(horizontalEdgesNewSize + (self.options.horizontal_border_size_offset or 0), 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
if (preset.use_titlebar) then
frame:CreateTitleBar()
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?
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.__rcorners) then
return
end
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
frame.options.horizontal_border_size_offset = preset.horizontal_border_size_offset
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)
+14 -65
View File
@@ -1,6 +1,6 @@
local dversion = 482
local dversion = 484
local major, minor = "DetailsFramework-1.0", dversion
local DF, oldminor = LibStub:NewLibrary(major, minor)
@@ -49,6 +49,8 @@ function DF:MsgWarning(msg, ...)
print("|cFFFFFFAA" .. (self.__name or "Details!Framework") .. "|r |cFFFFAA00[Warning]|r", msg, ...)
end
DF.internalFunctions = DF.internalFunctions or {}
local PixelUtil = PixelUtil or DFPixelUtil
if (not PixelUtil) then
--check if is in classic, TBC, or WotLK wow, if it is, build a replacement for PixelUtil
@@ -514,6 +516,8 @@ function DF.table.getfrompath(t, path)
end
return value
else
return t[path] or t[tonumber(path)]
end
end
@@ -539,7 +543,12 @@ function DF.table.setfrompath(t, path, value)
lastTable[lastKey] = value
return true
end
else
t[path] = value
return true
end
return false
end
---find the value inside the table, and it it's not found, add it
@@ -1888,7 +1897,7 @@ local anchoringFunctions = {
---set the anchor point using a df_anchor table
---@param widget uiobject
---@param anchorTable df_anchor
---@param anchorTo uiobject
---@param anchorTo uiobject?
function DF:SetAnchor(widget, anchorTable, anchorTo)
anchorTo = anchorTo or widget:GetParent()
anchoringFunctions[anchorTable.side](widget, anchorTo, anchorTable.x, anchorTable.y)
@@ -2093,67 +2102,6 @@ end
TutorialAlertFrame:Show()
end
local refresh_options = function(self)
for _, widget in ipairs(self.widget_list) do
if (widget._get) then
if (widget.widget_type == "label") then
if (widget._get() and not widget.languageAddonId) then
widget:SetText(widget._get())
end
elseif (widget.widget_type == "select") then
widget:Select(widget._get())
elseif (widget.widget_type == "toggle" or widget.widget_type == "range") then
widget:SetValue(widget._get())
elseif (widget.widget_type == "textentry") then
widget:SetText(widget._get())
elseif (widget.widget_type == "color") then
local default_value, g, b, a = widget._get()
if (type(default_value) == "table") then
widget:SetColor (unpack(default_value))
else
widget:SetColor (default_value, g, b, a)
end
end
end
end
end
local get_frame_by_id = function(self, id)
return self.widgetids [id]
end
function DF:ClearOptionsPanel(frame)
for i = 1, #frame.widget_list do
frame.widget_list[i]:Hide()
if (frame.widget_list[i].hasLabel) then
frame.widget_list[i].hasLabel:SetText("")
end
end
table.wipe(frame.widgetids)
end
function DF:SetAsOptionsPanel(frame)
frame.RefreshOptions = refresh_options
frame.widget_list = {}
frame.widget_list_by_type = {
["dropdown"] = {}, -- "select"
["switch"] = {}, -- "toggle"
["slider"] = {}, -- "range"
["color"] = {}, --
["button"] = {}, -- "execute"
["textentry"] = {}, --
["label"] = {}, --"text"
}
frame.widgetids = {}
frame.GetWidgetById = get_frame_by_id
end
function DF:CreateOptionsFrame(name, title, template)
template = template or 1
@@ -2162,7 +2110,7 @@ end
tinsert(UISpecialFrames, name)
newOptionsFrame:SetSize(500, 200)
newOptionsFrame.RefreshOptions = refresh_options
newOptionsFrame.RefreshOptions = DF.internalFunctions.RefreshOptionsPanel
newOptionsFrame.widget_list = {}
newOptionsFrame:SetScript("OnMouseDown", function(self, button)
@@ -2200,7 +2148,7 @@ end
tinsert(UISpecialFrames, name)
newOptionsFrame:SetSize(500, 200)
newOptionsFrame.RefreshOptions = refresh_options
newOptionsFrame.RefreshOptions = DF.internalFunctions.RefreshOptionsPanel
newOptionsFrame.widget_list = {}
newOptionsFrame:SetScript("OnMouseDown", function(self, button)
@@ -2703,6 +2651,7 @@ function DF:CreateAnimation(animation, animationType, order, duration, arg1, arg
elseif (animationType == "ROTATION") then
anim:SetDegrees(arg1) --degree
--print("SetOrigin", arg2, arg3, arg4)
anim:SetOrigin(arg2 or "center", arg3 or 0, arg4 or 0) --point, x, y
elseif (animationType == "TRANSLATION") then
+11
View File
@@ -706,6 +706,17 @@ local canvasScrollBoxDefaultOptions = {
function detailsFramework:CreateCanvasScrollBox(parent, child, name, options)
---@type df_canvasscrollbox
local canvasScrollBox = CreateFrame("scrollframe", name or ("DetailsFrameworkCanvasScroll" .. math.random(50000, 10000000)), parent, "BackdropTemplate, UIPanelScrollFrameTemplate")
canvasScrollBox.scrollStep = 20
canvasScrollBox:SetScript("OnMouseWheel", function(self, value)
local scrollBar = self
local scrollStep = scrollBar.scrollStep or scrollBar:GetHeight() / 2
if ( value > 0 ) then
scrollBar:SetVerticalScroll(scrollBar:GetVerticalScroll() - scrollStep)
else
scrollBar:SetVerticalScroll(scrollBar:GetVerticalScroll() + scrollStep)
end
end)
detailsFramework:Mixin(canvasScrollBox, detailsFramework.CanvasScrollBoxMixin)
detailsFramework:Mixin(canvasScrollBox, detailsFramework.OptionsFunctions)
+17 -11
View File
@@ -232,6 +232,11 @@ DF:Mixin(DFSliderMetaFunctions, DF.ScriptHookMixin)
return self(value)
end
function DFSliderMetaFunctions:SetValueNoCallback(value)
self.NoCallback = true
self.slider:SetValue(value)
end
-- thumb size
function DFSliderMetaFunctions:SetThumbSize(width, height)
if (not width) then
@@ -697,6 +702,18 @@ DF:Mixin(DFSliderMetaFunctions, DF.ScriptHookMixin)
table.insert(object.previous_value, 1, amt)
table.remove(object.previous_value, 4)
if (object.useDecimals) then
slider.amt:SetText(string.format("%.2f", amt))
else
slider.amt:SetText(math.floor(amt))
end
object.ivalue = amt
if (object.NoCallback) then
object.NoCallback = false
return
end
--some plugins registered OnValueChanged and others with OnValueChange
local kill = object:RunHooksForWidget("OnValueChanged", slider, object.FixedValue, amt, object)
if (kill) then
@@ -711,17 +728,6 @@ DF:Mixin(DFSliderMetaFunctions, DF.ScriptHookMixin)
if (object.OnValueChanged) then
object.OnValueChanged(slider, object.FixedValue, amt)
end
if (amt < 10 and amt >= 1) then
amt = "0" .. amt
end
if (object.useDecimals) then
slider.amt:SetText(string.format("%.2f", amt))
else
slider.amt:SetText(math.floor(amt))
end
object.ivalue = amt
end
------------------------------------------------------------------------------------------------------------
+13 -2
View File
@@ -271,6 +271,8 @@ function detailsFramework:CreateTabContainer(parent, title, frameName, tabList,
local buttonTextSize = optionsTable.button_text_size or 10
local containerWidthOffset = optionsTable.container_width_offset or 0
local bFirstTabIsCreateOnDemand = false
--create the base frame
---@type df_tabcontainer
local tabContainer = CreateFrame("frame", frameName, parent["widget"] or parent, "BackdropTemplate")
@@ -318,10 +320,14 @@ function detailsFramework:CreateTabContainer(parent, title, frameName, tabList,
if (tabInfo.createOnDemandFunc) then
tabFrame:SetScript("OnShow", function()
if (tabInfo.createOnDemandFunc) then
detailsFramework:Dispatch(tabInfo.createOnDemandFunc, tabFrame, parent)
detailsFramework:Dispatch(tabInfo.createOnDemandFunc, tabFrame, tabContainer, parent)
tabInfo.createOnDemandFunc = nil
end
end)
if (tabIndex == 1) then
bFirstTabIsCreateOnDemand = true
end
end
--attempt to get the localized text from the language system using the addonId and the frameInfo.text
@@ -405,7 +411,12 @@ function detailsFramework:CreateTabContainer(parent, title, frameName, tabList,
tabContainer:SetScript("OnShow", tabContainer.OnShow)
--select the first frame
local defaultTab = 1
tabContainer:SelectTabByIndex(defaultTab)
if (bFirstTabIsCreateOnDemand) then
C_Timer.After(0, function() tabContainer:SelectTabByIndex(defaultTab) end)
else
tabContainer:SelectTabByIndex(defaultTab)
end
return tabContainer
end
+1
View File
@@ -1937,6 +1937,7 @@ function detailsFramework:CreateCastBar(parent, name, settingsOverride)
detailsFramework:Mixin(castBar, detailsFramework.CastFrameFunctions)
detailsFramework:Mixin(castBar, detailsFramework.StatusBarFunctions)
castBar:CreateTextureMask()
castBar:AddMaskTexture(castBar.flashTexture)
castBar:AddMaskTexture(castBar.background)
+1 -1
View File
@@ -39,7 +39,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and not isExpansion_Dragonflight()) t
end
local major = "LibOpenRaid-1.0"
local CONST_LIB_VERSION = 113
local CONST_LIB_VERSION = 114
if (LIB_OPEN_RAID_MAX_VERSION) then
if (CONST_LIB_VERSION <= LIB_OPEN_RAID_MAX_VERSION) then
@@ -547,7 +547,10 @@ do
[5384] = {cooldown = 30, duration = 0, specs = {}, talent = false, charges = 1, class = "HUNTER", type = 5}, --Feign Death
[186387] = {cooldown = 30, duration = 6, specs = {}, talent = false, charges = 1, class = "HUNTER", type = 8}, --Bursting Shot
[236776] = {cooldown = 40, duration = 0, specs = {253, 254, 255}, talent = false, charges = 1, class = "HUNTER", type = 8}, --High Explosive Trap
[272682] = {cooldown = 45, duration = 4, specs = {253, 254, 255}, talent = false, charges = 1, class = "HUNTER", type = 7}, --Master's Call
--Boar nil 62305 Master's Call
--Boar Tiranaa 54216 Master's Call
--Tiranaa Tiranaa 272682 Master's Call
--~druid
-- 102 - Balance