Maintenance Update and Mythic Dungeon Plus development progress
- Dungeon followers now correctly show into the damage done section. - Fixed an error while statusbar plugin options. - Framework update. - Mythic Dungeon Plus code has been separated into six files (was just 2), this will help with the organization and maintenance of the code.
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
---@field internalFunctions table
|
||||
---@field OptionsFunctions df_optionsmixin
|
||||
---@field GlobalWidgetControlNames table
|
||||
---@field DefaultRoundedCornerPreset table
|
||||
---@field RoundedCornerPanelMixin df_roundedcornermixin
|
||||
---@field Schedules df_schedule
|
||||
---@field HeaderFunctions df_headerfunctions
|
||||
@@ -142,6 +143,8 @@
|
||||
---@field IsHtmlColor fun(self:table, colorName:any) : unknown return true if DF.alias_text_colors has the colorName as a key
|
||||
---@field CreateColorTable fun(self:table, r:number, g:number, b:number, a:number) : table return a table with {r, g, b, a}
|
||||
---@field FormatColor fun(self:table, newFormat:string, r:number|string, g:number?, b:number?, a:number?, decimalsAmount:number?) : string|table|number|nil, number|nil, number|nil, number|nil takes in a color in one format and converts it to another specified format.
|
||||
---@field
|
||||
---@field CreateEditor fun(self:table, parent:frame, name:string?, options:df_editor_defaultoptions?) : df_editor
|
||||
---@field RandomBool fun(self:table, odds: number?) : boolean return a random boolean
|
||||
---@field CreateHighlightTexture fun(self:table, parent:frame, parentKey:string?, alpha:number?, name:string?) : texture
|
||||
---@field
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@ function DropDownMetaFunctions:Select(optionName, byOptionNumber, bOnlyShown, ru
|
||||
return false
|
||||
end
|
||||
|
||||
local optionsTable = DF:Dispatch(self.func, self) --399
|
||||
local runOkay, optionsTable = xpcall(self.func, geterrorhandler(), self)
|
||||
|
||||
if (#optionsTable == 0) then
|
||||
self:NoOption(true)
|
||||
@@ -563,6 +563,11 @@ function DropDownMetaFunctions:Selected(thisOption)
|
||||
self.statusbar:SetTexture([[Interface\Tooltips\CHATBUBBLE-BACKGROUND]])
|
||||
end
|
||||
|
||||
if (self.widget.__rcorners) then
|
||||
self.statusbar:SetPoint("topleft", self.widget, "topleft", 2, -2)
|
||||
self.statusbar:SetPoint("bottomright", self.widget, "bottomright", -2, 2)
|
||||
end
|
||||
|
||||
if (thisOption.color) then
|
||||
local r, g, b, a = DF:ParseColors(thisOption.color)
|
||||
self.label:SetTextColor(r, g, b, a)
|
||||
|
||||
+164
-89
@@ -21,8 +21,25 @@ local _
|
||||
--the editor doesn't know which key in the profileTable holds the current value for an attribute, so it uses a map table to find it.
|
||||
--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 : 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_attribute
|
||||
---@field name string?
|
||||
---@field key string?
|
||||
---@field label string?
|
||||
---@field widget string
|
||||
---@field default any?
|
||||
@@ -32,19 +49,31 @@ local _
|
||||
---@field usedecimals boolean?
|
||||
---@field subkey string?
|
||||
|
||||
---@class df_editor_objectinfo : table
|
||||
---@field object uiobject
|
||||
---@field label string
|
||||
---@field id any
|
||||
---@field profiletable table
|
||||
---@field profilekeymap table
|
||||
---@field subtablepath string?
|
||||
---@field extraoptions table
|
||||
---@field callback function?
|
||||
---@field options df_editobjectoptions
|
||||
---@field selectButton button
|
||||
|
||||
--which object attributes are used to build the editor menu for each object type
|
||||
local attributes = {
|
||||
---@type df_editor_attribute[]
|
||||
FontString = {
|
||||
{
|
||||
name = "text",
|
||||
key = "text",
|
||||
label = "Text",
|
||||
widget = "textentry",
|
||||
default = "font string text",
|
||||
setter = function(widget, value) widget:SetText(value) end,
|
||||
},
|
||||
{
|
||||
name = "size",
|
||||
key = "size",
|
||||
label = "Size",
|
||||
widget = "range",
|
||||
minvalue = 5,
|
||||
@@ -52,7 +81,7 @@ local attributes = {
|
||||
setter = function(widget, value) widget:SetFont(widget:GetFont(), value, select(3, widget:GetFont())) end
|
||||
},
|
||||
{
|
||||
name = "font",
|
||||
key = "font",
|
||||
label = "Font",
|
||||
widget = "fontdropdown",
|
||||
setter = function(widget, value)
|
||||
@@ -61,32 +90,32 @@ local attributes = {
|
||||
end
|
||||
},
|
||||
{
|
||||
name = "color",
|
||||
key = "color",
|
||||
label = "Color",
|
||||
widget = "color",
|
||||
setter = function(widget, value) widget:SetTextColor(unpack(value)) end
|
||||
},
|
||||
{
|
||||
name = "alpha",
|
||||
key = "alpha",
|
||||
label = "Alpha",
|
||||
widget = "range",
|
||||
setter = function(widget, value) widget:SetAlpha(value) end
|
||||
},
|
||||
{widget = "blank"},
|
||||
{
|
||||
name = "shadow",
|
||||
key = "shadow",
|
||||
label = "Draw Shadow",
|
||||
widget = "toggle",
|
||||
setter = function(widget, value) widget:SetShadowColor(widget:GetShadowColor(), select(2, widget:GetShadowColor()), select(3, widget:GetShadowColor()), value and 0.5 or 0) end
|
||||
},
|
||||
{
|
||||
name = "shadowcolor",
|
||||
key = "shadowcolor",
|
||||
label = "Shadow Color",
|
||||
widget = "color",
|
||||
setter = function(widget, value) widget:SetShadowColor(unpack(value)) end
|
||||
},
|
||||
{
|
||||
name = "shadowoffsetx",
|
||||
key = "shadowoffsetx",
|
||||
label = "Shadow X Offset",
|
||||
widget = "range",
|
||||
minvalue = -10,
|
||||
@@ -94,7 +123,7 @@ local attributes = {
|
||||
setter = function(widget, value) widget:SetShadowOffset(value, select(2, widget:GetShadowOffset())) end
|
||||
},
|
||||
{
|
||||
name = "shadowoffsety",
|
||||
key = "shadowoffsety",
|
||||
label = "Shadow Y Offset",
|
||||
widget = "range",
|
||||
minvalue = -10,
|
||||
@@ -102,20 +131,20 @@ local attributes = {
|
||||
setter = function(widget, value) widget:SetShadowOffset(widget:GetShadowOffset(), value) end
|
||||
},
|
||||
{
|
||||
name = "outline",
|
||||
key = "outline",
|
||||
label = "Outline",
|
||||
widget = "outlinedropdown",
|
||||
setter = function(widget, value) widget:SetFont(widget:GetFont(), select(2, widget:GetFont()), value) end
|
||||
},
|
||||
{widget = "blank"},
|
||||
{
|
||||
name = "anchor",
|
||||
key = "anchor",
|
||||
label = "Anchor",
|
||||
widget = "anchordropdown",
|
||||
setter = function(widget, value) detailsFramework:SetAnchor(widget, value, widget:GetParent()) end
|
||||
},
|
||||
{
|
||||
name = "anchoroffsetx",
|
||||
key = "anchoroffsetx",
|
||||
label = "Anchor X Offset",
|
||||
widget = "range",
|
||||
minvalue = -100,
|
||||
@@ -123,7 +152,7 @@ local attributes = {
|
||||
setter = function(widget, value) detailsFramework:SetAnchor(widget, value, widget:GetParent()) end
|
||||
},
|
||||
{
|
||||
name = "anchoroffsety",
|
||||
key = "anchoroffsety",
|
||||
label = "Anchor Y Offset",
|
||||
widget = "range",
|
||||
minvalue = -100,
|
||||
@@ -131,7 +160,7 @@ local attributes = {
|
||||
setter = function(widget, value) detailsFramework:SetAnchor(widget, value, widget:GetParent()) end
|
||||
},
|
||||
{
|
||||
name = "rotation",
|
||||
key = "rotation",
|
||||
label = "Rotation",
|
||||
widget = "range",
|
||||
usedecimals = true,
|
||||
@@ -140,7 +169,7 @@ local attributes = {
|
||||
setter = function(widget, value) widget:SetRotation(value) end
|
||||
},
|
||||
{
|
||||
name = "scale",
|
||||
key = "scale",
|
||||
label = "Scale",
|
||||
widget = "range",
|
||||
usedecimals = true,
|
||||
@@ -161,24 +190,38 @@ local attributes = {
|
||||
---@field GetOptionsFrame fun(self:df_editor):frame
|
||||
---@field GetCanvasScrollBox fun(self:df_editor):df_canvasscrollbox
|
||||
---@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 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)
|
||||
---@field RegisterObject fun(self:df_editor, object:uiobject, localizedLabel:string, id:any, profileTable:table, subTablePath:string, profileKeyMap:table, extraOptions:table?, callback:function?, options:df_editobjectoptions?):df_editor_objectinfo
|
||||
---@field UnregisterObject fun(self:df_editor, object:uiobject)
|
||||
---@field EditObjectById fun(self:df_editor, id:any)
|
||||
---@field EditObjectByIndex fun(self:df_editor, index:number)
|
||||
---@field UpdateGuideLinesAnchors fun(self:df_editor)
|
||||
---@field GetObjectByRef fun(self:df_editor, object:uiobject):df_editor_objectinfo
|
||||
---@field GetObjectByIndex fun(self:df_editor, index:number):df_editor_objectinfo
|
||||
---@field GetObjectById fun(self:df_editor, id:any):df_editor_objectinfo
|
||||
---@field CreateObjectSelectionList fun(self:df_editor, scroll_width:number, scroll_height:number, scroll_lines:number, scroll_line_height:number):df_scrollbox
|
||||
---@field OnHide fun(self:df_editor)
|
||||
---@field UpdateProfileTableOnAllRegisteredObjects fun(self:df_editor, profileTable:table)
|
||||
---@field GetProfileTableFromObject fun(self:df_editor, object:df_editor_objectinfo):table
|
||||
|
||||
---@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
|
||||
---@field text_template table
|
||||
|
||||
---@type df_editobjectoptions
|
||||
local editObjectDefaultOptions = {
|
||||
use_colon = true,
|
||||
use_colon = false,
|
||||
can_move = true,
|
||||
use_guide_lines = true,
|
||||
text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"),
|
||||
}
|
||||
|
||||
local getParentTable = function(profileTable, profileKey)
|
||||
@@ -269,12 +312,14 @@ detailsFramework.EditorMixin = {
|
||||
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
|
||||
|
||||
local profileTable = self:GetProfileTableFromObject(registeredObject)
|
||||
assert(type(profileTable) == "table", "EditObject() profileTable is invalid.")
|
||||
|
||||
--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
|
||||
@@ -338,7 +383,7 @@ detailsFramework.EditorMixin = {
|
||||
end
|
||||
end,
|
||||
|
||||
PrepareObjectForEditing = function(self)
|
||||
PrepareObjectForEditing = function(self) --~edit
|
||||
--get the object and its profile table with the current values
|
||||
local object = self:GetEditingObject()
|
||||
local profileTable, profileMap = self:GetEditingProfile()
|
||||
@@ -390,7 +435,7 @@ detailsFramework.EditorMixin = {
|
||||
menuOptions[#menuOptions+1] = {type = "blank"}
|
||||
else
|
||||
--get the key to be used on profile table
|
||||
local profileKey = profileMap[option.name]
|
||||
local profileKey = profileMap[option.key]
|
||||
local value
|
||||
|
||||
--if the key contains a dot or a bracket, it means it's a table path, example: "text_settings[1].width"
|
||||
@@ -410,10 +455,10 @@ detailsFramework.EditorMixin = {
|
||||
local minValue = option.minvalue
|
||||
local maxValue = option.maxvalue
|
||||
|
||||
if (option.name == "anchoroffsetx") then
|
||||
if (option.key == "anchoroffsetx") then
|
||||
minValue = -object:GetParent():GetWidth()/2
|
||||
maxValue = object:GetParent():GetWidth()/2
|
||||
elseif (option.name == "anchoroffsety") then
|
||||
elseif (option.key == "anchoroffsety") then
|
||||
minValue = -object:GetParent():GetHeight()/2
|
||||
maxValue = object:GetParent():GetHeight()/2
|
||||
end
|
||||
@@ -421,7 +466,7 @@ detailsFramework.EditorMixin = {
|
||||
if (bHasValue) then
|
||||
local parentTable = getParentTable(profileTable, profileKey)
|
||||
|
||||
if (option.name == "anchor" or option.name == "anchoroffsetx" or option.name == "anchoroffsety") then
|
||||
if (option.key == "anchor" or option.key == "anchoroffsetx" or option.key == "anchoroffsety") then
|
||||
anchorSettings = parentTable
|
||||
end
|
||||
|
||||
@@ -446,20 +491,20 @@ detailsFramework.EditorMixin = {
|
||||
parentTable[4] = alpha
|
||||
|
||||
newValue = parentTable
|
||||
else
|
||||
detailsFramework.table.setfrompath(profileTable, profileKey, newValue)
|
||||
end
|
||||
|
||||
detailsFramework.table.setfrompath(profileTable, profileKey, newValue)
|
||||
|
||||
if (self:GetOnEditCallback()) then
|
||||
self:GetOnEditCallback()(object, option.name, newValue, profileTable, profileKey)
|
||||
self:GetOnEditCallback()(object, option.key, 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
|
||||
if (option.key == "anchor" or option.key == "anchoroffsetx" or option.key == "anchoroffsety") then
|
||||
anchorSettings = parentTable
|
||||
|
||||
if (option.name == "anchor") then
|
||||
if (option.key == "anchor") then
|
||||
anchorSettings.x = 0
|
||||
anchorSettings.y = 0
|
||||
end
|
||||
@@ -479,7 +524,7 @@ detailsFramework.EditorMixin = {
|
||||
max = maxValue,
|
||||
step = option.step,
|
||||
usedecimals = option.usedecimals,
|
||||
id = option.name,
|
||||
id = option.key,
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -504,13 +549,14 @@ detailsFramework.EditorMixin = {
|
||||
optionsFrame:SetHeight(optionsFrameHeight)
|
||||
|
||||
--templates
|
||||
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_text_template = self.options.text_template or detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = detailsFramework:GetTemplate("button", "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)
|
||||
--~build ~menu ~volatile
|
||||
detailsFramework:BuildMenuVolatile(optionsFrame, menuOptions, 2, -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)
|
||||
@@ -539,8 +585,14 @@ detailsFramework.EditorMixin = {
|
||||
|
||||
local optionsFrame = self:GetOptionsFrame()
|
||||
|
||||
--getting the size this way due to the cascade of different scales that are applyed to unitFrame objects
|
||||
moverFrame:ClearAllPoints()
|
||||
moverFrame:SetPoint("topleft", object, "topleft", -5, 5)
|
||||
moverFrame:SetPoint("bottomright", object, "bottomright", 5, -5)
|
||||
local moverWidth, moverHeight = moverFrame:GetSize()
|
||||
|
||||
local objectWidth, objectHeight = object:GetSize()
|
||||
moverFrame:SetSize(objectWidth, objectHeight)
|
||||
moverFrame:SetSize(moverWidth, moverHeight)
|
||||
detailsFramework:SetAnchor(moverFrame, anchorSettings, object:GetParent())
|
||||
local currentPosX, currentPosY
|
||||
|
||||
@@ -557,6 +609,10 @@ detailsFramework.EditorMixin = {
|
||||
moverFrame:StopMovingOrSizing()
|
||||
moverFrame.bIsMoving = false
|
||||
|
||||
--0.64 UIParent
|
||||
--0.96 object
|
||||
--local scale = object:GetEffectiveScale() / UIParent:GetEffectiveScale() --1.5
|
||||
|
||||
local originX = anchorSettings.x
|
||||
local originY = anchorSettings.y
|
||||
|
||||
@@ -565,8 +621,11 @@ detailsFramework.EditorMixin = {
|
||||
local xOffset = newPosX - currentPosX
|
||||
local yOffset = newPosY - currentPosY
|
||||
|
||||
anchorSettings.x = originX + xOffset
|
||||
anchorSettings.y = originY + yOffset
|
||||
xOffset = xOffset
|
||||
yOffset = yOffset
|
||||
|
||||
anchorSettings.x = (originX + xOffset)
|
||||
anchorSettings.y = (originY + yOffset)
|
||||
|
||||
local anchorXSlider = optionsFrame:GetWidgetById("anchoroffsetx")
|
||||
anchorXSlider:SetValueNoCallback(anchorSettings.x)
|
||||
@@ -576,12 +635,24 @@ detailsFramework.EditorMixin = {
|
||||
|
||||
object:ClearAllPoints()
|
||||
detailsFramework:SetAnchor(object, anchorSettings, object:GetParent())
|
||||
|
||||
--save the new position
|
||||
local profileTable, profileMap = self:GetEditingProfile()
|
||||
local profileKey = profileMap.anchor
|
||||
local parentTable = getParentTable(profileTable, profileKey)
|
||||
parentTable.x = anchorSettings.x
|
||||
parentTable.y = anchorSettings.y
|
||||
|
||||
if (self:GetOnEditCallback()) then
|
||||
self:GetOnEditCallback()(object, "x", anchorSettings.x, profileTable, profileKey)
|
||||
self:GetOnEditCallback()(object, "y", anchorSettings.x, profileTable, profileKey)
|
||||
end
|
||||
end)
|
||||
|
||||
--detailsFramework:SetAnchor(moverFrame, anchorSettings)
|
||||
--detailsFramework:SetAnchor(object, anchorSettings, moverFrame)
|
||||
|
||||
moverFrame:SetScript("OnUpdate", function()
|
||||
moverFrame:SetScript("OnUpdate", function() --not in use
|
||||
--if the object isn't moving, make the mover follow the object position
|
||||
if (false and moverFrame.bIsMoving) then
|
||||
--object:ClearAllPoints()
|
||||
@@ -607,19 +678,6 @@ detailsFramework.EditorMixin = {
|
||||
|
||||
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,
|
||||
|
||||
@@ -638,7 +696,36 @@ detailsFramework.EditorMixin = {
|
||||
moverFrame:Hide()
|
||||
end,
|
||||
|
||||
RegisterObject = function(self, object, localizedLabel, id, profileTable, profileKeyMap, extraOptions, callback, options)
|
||||
---@param self df_editor
|
||||
---@param object df_editor_objectinfo
|
||||
GetProfileTableFromObject = function(self, object)
|
||||
local profileTable = object.profiletable
|
||||
local subTablePath = object.subtablepath
|
||||
|
||||
if (type(subTablePath) == "string" and subTablePath ~= "") then
|
||||
local subTable = detailsFramework.table.getfrompath(profileTable, subTablePath)
|
||||
assert(type(subTable) == "table", "GetProfileTableFromObject() subTablePath is invalid.")
|
||||
return subTable
|
||||
end
|
||||
|
||||
return profileTable
|
||||
end,
|
||||
|
||||
UpdateProfileTableOnAllRegisteredObjects = function(self, profileTable)
|
||||
assert(type(profileTable) == "table", "UpdateProfileTableOnAllRegisteredObjects() expects a table on #1 parameter.")
|
||||
|
||||
local registeredObjects = self:GetAllRegisteredObjects()
|
||||
|
||||
for i = 1, #registeredObjects do
|
||||
local objectRegistered = registeredObjects[i]
|
||||
objectRegistered.profiletable = profileTable
|
||||
end
|
||||
|
||||
local objectSelector = self:GetObjectSelector()
|
||||
objectSelector:RefreshMe()
|
||||
end,
|
||||
|
||||
RegisterObject = function(self, object, localizedLabel, id, profileTable, subTablePath, 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.")
|
||||
@@ -671,6 +758,7 @@ detailsFramework.EditorMixin = {
|
||||
label = localizedLabel,
|
||||
id = id,
|
||||
profiletable = profileTable,
|
||||
subtablepath = subTablePath,
|
||||
profilekeymap = profileKeyMap,
|
||||
extraoptions = extraOptions or {},
|
||||
callback = callback,
|
||||
@@ -741,6 +829,10 @@ detailsFramework.EditorMixin = {
|
||||
local editorFrame = self
|
||||
|
||||
local refreshFunc = function(self, data, offset, totalLines) --~refresh
|
||||
self.SelectionTexture:Hide()
|
||||
self.SelectionTexture:ClearAllPoints()
|
||||
local objectCurrentBeingEdited = editorFrame:GetEditingObject()
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
---@type df_editor_objectinfo
|
||||
@@ -749,16 +841,20 @@ detailsFramework.EditorMixin = {
|
||||
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)
|
||||
if (objectRegistered.object:GetObjectType() == "Texture") then
|
||||
line.Icon:SetAtlas("AnimCreate_Icon_Texture")
|
||||
|
||||
elseif (objectRegistered.object:GetObjectType() == "FontString") then
|
||||
line.Icon:SetAtlas("AnimCreate_Icon_Text")
|
||||
end
|
||||
|
||||
line.Label:SetText(objectRegistered.label)
|
||||
|
||||
if (objectRegistered.object == objectCurrentBeingEdited) then
|
||||
self.SelectionTexture:SetAllPoints(line)
|
||||
self.SelectionTexture:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -775,14 +871,13 @@ detailsFramework.EditorMixin = {
|
||||
line:SetBackdropColor(.1, .1, .1, .4)
|
||||
end
|
||||
|
||||
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||||
|
||||
--line:SetScript("OnEnter", lineOnEnter)
|
||||
--line:SetScript("OnLeave", lineOnLeave)
|
||||
detailsFramework:CreateHighlightTexture(line, "HighlightTexture")
|
||||
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||||
|
||||
line:SetScript("OnClick", function(self)
|
||||
local objectRegistered = editorFrame:GetObjectByIndex(self.index)
|
||||
editorFrame:EditObject(objectRegistered)
|
||||
editorFrame.objectSelector:RefreshMe()
|
||||
end)
|
||||
|
||||
--icon
|
||||
@@ -804,6 +899,10 @@ detailsFramework.EditorMixin = {
|
||||
local selectObjectScrollBox = detailsFramework:CreateScrollBox(self:GetParent(), "$parentSelectObjectScrollBox", refreshFunc, editorFrame:GetAllRegisteredObjects(), scroll_width, scroll_height, scroll_lines, scroll_line_height)
|
||||
detailsFramework:ReskinSlider(selectObjectScrollBox)
|
||||
|
||||
local selectionTexture = selectObjectScrollBox:CreateTexture(nil, "overlay")
|
||||
selectionTexture:SetColorTexture(1, 1, 0, 0.2)
|
||||
selectObjectScrollBox.SelectionTexture = selectionTexture
|
||||
|
||||
function selectObjectScrollBox:RefreshMe()
|
||||
selectObjectScrollBox:SetData(editorFrame:GetAllRegisteredObjects())
|
||||
selectObjectScrollBox:Refresh()
|
||||
@@ -831,8 +930,11 @@ detailsFramework.EditorMixin = {
|
||||
---@field object_list_height number
|
||||
---@field object_list_lines number
|
||||
---@field object_list_line_height number
|
||||
---@field text_template table
|
||||
|
||||
---@class df_editor_defaultoptions
|
||||
--editorFrame.options.text_template
|
||||
|
||||
---@type df_editor_defaultoptions
|
||||
local editorDefaultOptions = {
|
||||
width = 400,
|
||||
height = 548,
|
||||
@@ -842,36 +944,9 @@ local editorDefaultOptions = {
|
||||
object_list_height = 420,
|
||||
object_list_lines = 20,
|
||||
object_list_line_height = 20,
|
||||
text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"),
|
||||
}
|
||||
|
||||
---@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
|
||||
---@field selectButton button
|
||||
|
||||
function detailsFramework:CreateEditor(parent, name, options)
|
||||
name = name or ("DetailsFrameworkEditor" .. math.random(100000, 10000000))
|
||||
local editorFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||||
|
||||
+23
-2
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
local dversion = 507
|
||||
local dversion = 510
|
||||
local major, minor = "DetailsFramework-1.0", dversion
|
||||
local DF, oldminor = LibStub:NewLibrary(major, minor)
|
||||
|
||||
@@ -49,6 +49,12 @@ function DF:MsgWarning(msg, ...)
|
||||
print("|cFFFFFFAA" .. (self.__name or "Details!Framework") .. "|r |cFFFFAA00[Warning]|r", msg, ...)
|
||||
end
|
||||
|
||||
DF.DefaultRoundedCornerPreset = {
|
||||
roundness = 6,
|
||||
color = {.1, .1, .1, 0.98},
|
||||
border_color = {.05, .05, .05, 0.834},
|
||||
}
|
||||
|
||||
DF.internalFunctions = DF.internalFunctions or {}
|
||||
|
||||
local PixelUtil = PixelUtil or DFPixelUtil
|
||||
@@ -506,6 +512,16 @@ function DF:FadeFrame(frame, t)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
function DF:RandomBool(odds)
|
||||
if (odds) then
|
||||
local chance = math.random()
|
||||
return chance <= odds
|
||||
else
|
||||
return math.random(1, 2) == 1
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
--table
|
||||
|
||||
@@ -804,6 +820,7 @@ function DF.table.deploy(t1, t2)
|
||||
return t1
|
||||
end
|
||||
|
||||
--/run print (DetailsFramework.table.dump({{1, 2}, {2, 3}, {4, 5}}))
|
||||
local function tableToString(t, resultString, deep, seenTables)
|
||||
resultString = resultString or ""
|
||||
deep = deep or 0
|
||||
@@ -853,7 +870,11 @@ local function tableToString(t, resultString, deep, seenTables)
|
||||
resultString = resultString .. space .. "[\"" .. key .. "\"] = \"|cFFfff1c1" .. value .. "|r\",\n"
|
||||
|
||||
elseif (valueType == "number") then
|
||||
resultString = resultString .. space .. "[\"" .. key .. "\"] = |cFF94CEA8" .. value .. "|r,\n"
|
||||
if (type(key) == "number") then
|
||||
resultString = resultString .. space .. "[" .. key .. "] = |cFFffc1f4" .. value .. "|r,\n"
|
||||
else
|
||||
resultString = resultString .. space .. "[\"" .. key .. "\"] = |cFF94CEA8" .. value .. "|r,\n"
|
||||
end
|
||||
|
||||
elseif (valueType == "function") then
|
||||
resultString = resultString .. space .. "[\"" .. key .. "\"] = |cFFC586C0function|r,\n"
|
||||
|
||||
@@ -100,7 +100,7 @@ local default_load_conditions_frame_options = {
|
||||
|
||||
function detailsFramework:CreateLoadFilterParser(callback)
|
||||
local filterFrame = CreateFrame("frame")
|
||||
|
||||
|
||||
if IS_WOW_PROJECT_MAINLINE then
|
||||
filterFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
|
||||
filterFrame:RegisterEvent("TRAIT_CONFIG_LIST_UPDATED")
|
||||
@@ -117,11 +117,47 @@ function detailsFramework:CreateLoadFilterParser(callback)
|
||||
filterFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
filterFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
|
||||
filterFrame:RegisterEvent("CHAT_MSG_LOOT")
|
||||
|
||||
filterFrame:SetScript("OnEvent", function(self, event, ...)
|
||||
if (event == "ENCOUNTER_START") then --triggers before regen_disabled
|
||||
local encounterID = ...
|
||||
filterFrame.EncounterIDCached = encounterID
|
||||
|
||||
elseif (event == "CHAT_MSG_LOOT") then
|
||||
local message = ...
|
||||
local itemId = message:match("|Hitem:(%d+):")
|
||||
itemId = tonumber(itemId)
|
||||
|
||||
if (itemId == 191140) then
|
||||
xpcall(callback, geterrorhandler(), "RACE_START")
|
||||
--monitor the player backpack each second to know when the item is removed from the bag
|
||||
|
||||
C_Timer.After(5, function()
|
||||
filterFrame.FindBackpackItem = C_Timer.NewTicker(1, function()
|
||||
local bFoundItem = false
|
||||
for bagId = 0, 4 do
|
||||
for slotId = 1, 32 do
|
||||
local bagItemID = C_Container.GetContainerItemID(bagId, slotId)
|
||||
if (bagItemID) then
|
||||
if (bagItemID == itemId) then
|
||||
--bronze timepiece is on the player backpack
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (not bFoundItem) then
|
||||
filterFrame.FindBackpackItem:Cancel()
|
||||
xpcall(callback, geterrorhandler(), "RACE_STOP")
|
||||
return
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
return
|
||||
|
||||
elseif (event == "PLAYER_REGEN_DISABLED") then
|
||||
|
||||
elseif (event == "ENCOUNTER_END") then
|
||||
@@ -157,7 +193,8 @@ function detailsFramework:CreateLoadFilterParser(callback)
|
||||
detailsFramework.CurrentPlayerRole = assignedRole
|
||||
end
|
||||
|
||||
detailsFramework:QuickDispatch(callback, filterFrame.EncounterIDCached)
|
||||
--problem: this xpcall won't tell where the error happened in the callback code
|
||||
xpcall(callback, geterrorhandler(), filterFrame.EncounterIDCached)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -2085,7 +2085,7 @@ local no_options = {}
|
||||
---NoCloseButton = false, --if true, won't show the close button
|
||||
---NoTitleBar = false, --if true, don't create the title bar
|
||||
---RoundedCorners = false, --use rounded corners if true
|
||||
---@class simplepanel
|
||||
---@class simplepanel : frame
|
||||
---@field TitleBar frame
|
||||
---@field Title fontstring
|
||||
---@field Close button
|
||||
|
||||
@@ -367,3 +367,22 @@ detailsFramework:Mixin(ImageMetaFunctions, detailsFramework.ScriptHookMixin)
|
||||
|
||||
return ImageObject
|
||||
end
|
||||
|
||||
function detailsFramework:CreateHighlightTexture(parent, parentKey, alpha, name)
|
||||
if (not name) then
|
||||
name = "DetailsFrameworkPictureNumber" .. detailsFramework.PictureNameCounter
|
||||
detailsFramework.PictureNameCounter = detailsFramework.PictureNameCounter + 1
|
||||
end
|
||||
|
||||
local highlightTexture = parent:CreateTexture(name, "highlight")
|
||||
highlightTexture:SetTexture([[Interface\Buttons\WHITE8X8]])
|
||||
highlightTexture:SetAlpha(alpha or 0.1)
|
||||
highlightTexture:SetBlendMode("ADD")
|
||||
highlightTexture:SetAllPoints()
|
||||
|
||||
if (parentKey) then
|
||||
parent[parentKey] = highlightTexture
|
||||
end
|
||||
|
||||
return highlightTexture
|
||||
end
|
||||
@@ -411,6 +411,11 @@ detailsFramework.RoundedCornerPanelMixin = {
|
||||
alignment = alignment:lower()
|
||||
|
||||
if (alignment == "vertical") then
|
||||
if (self.tabSide) then
|
||||
if (self.tabSide == "top" or self.tabSide == "bottom") then
|
||||
return self:GetHeight() - (borderTexture:GetHeight() * 2) + 2 - borderTexture:GetHeight()
|
||||
end
|
||||
end
|
||||
return self:GetHeight() - (borderTexture:GetHeight() * 2) + 2
|
||||
|
||||
elseif (alignment == "horizontal") then
|
||||
@@ -678,6 +683,68 @@ function detailsFramework:AddRoundedCornersToFrame(frame, preset)
|
||||
applyPreset(frame, preset)
|
||||
else
|
||||
applyPreset(frame, defaultPreset)
|
||||
preset = defaultPreset
|
||||
end
|
||||
|
||||
if (preset.tab_side) then
|
||||
if (preset.tab_side == "top") then
|
||||
--hide the bottom textures of the rounded corner, the top and middle textures will be used to fill the tab
|
||||
frame.BottomHorizontalEdge:Hide()
|
||||
frame.BottomLeft:Hide()
|
||||
frame.BottomRight:Hide()
|
||||
|
||||
local point1, relativeTo, point2, x, y = frame.CornerTextures["TopLeft"]:GetPoint(1)
|
||||
frame.CornerTextures["TopLeft"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.CornerTextures["TopRight"]:GetPoint(1)
|
||||
frame.CornerTextures["TopRight"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
if (frame.BorderCornerTextures["TopLeft"]) then
|
||||
point1, relativeTo, point2, x, y = frame.BorderCornerTextures["TopLeft"]:GetPoint(1)
|
||||
frame.BorderCornerTextures["TopLeft"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.BorderCornerTextures["TopRight"]:GetPoint(1)
|
||||
frame.BorderCornerTextures["TopRight"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.TopEdgeBorder:GetPoint(1)
|
||||
frame.TopEdgeBorder:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
frame.BottomEdgeBorder:Hide()
|
||||
|
||||
frame.tabSide = "top"
|
||||
end
|
||||
|
||||
elseif (preset.tab_side == "bottom") then
|
||||
--hide the top textures of the rounded corner, the bottom and middle textures will be used to fill the tab
|
||||
frame.TopHorizontalEdge:Hide()
|
||||
frame.TopLeft:Hide()
|
||||
frame.TopRight:Hide()
|
||||
|
||||
local point1, relativeTo, point2, x, y = frame.CornerTextures["BottomLeft"]:GetPoint(1)
|
||||
frame.CornerTextures["BottomLeft"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.CornerTextures["BottomRight"]:GetPoint(1)
|
||||
frame.CornerTextures["BottomRight"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
if (frame.BorderCornerTextures["BottomLeft"]) then
|
||||
point1, relativeTo, point2, x, y = frame.BorderCornerTextures["BottomLeft"]:GetPoint(1)
|
||||
frame.BorderCornerTextures["BottomLeft"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.BorderCornerTextures["BottomRight"]:GetPoint(1)
|
||||
frame.BorderCornerTextures["BottomRight"]:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.BottomEdgeBorder:GetPoint(1)
|
||||
frame.BottomEdgeBorder:SetPoint(point1, relativeTo, point2, x, math.abs(preset.roundness -16))
|
||||
|
||||
frame.TopEdgeBorder:Hide()
|
||||
|
||||
point1, relativeTo, point2, x, y = frame.RightEdgeBorder:GetPoint(1)
|
||||
---@type height
|
||||
local verticalEdgeSize = frame:CalculateBorderEdgeSize("vertical")
|
||||
frame.RightEdgeBorder:SetHeight(verticalEdgeSize - 6)
|
||||
frame.tabSide = "bottom"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+155
-2
@@ -15,6 +15,16 @@ local UnitGUID = UnitGUID
|
||||
--create namespace
|
||||
detailsFramework.SavedVars = {}
|
||||
|
||||
function detailsFramework.SavedVars.GetCurrentProfileName(addonObject)
|
||||
assert(type(addonObject) == "table", "GetCurrentProfileName: addonObject must be a table.")
|
||||
|
||||
local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject)
|
||||
local playerGUID = UnitGUID("player")
|
||||
local profileId = savedVariables.profile_ids[playerGUID] --get the profile name from the player guid
|
||||
|
||||
return profileId
|
||||
end
|
||||
|
||||
---get the saved variables table for the addon
|
||||
---@param addonObject df_addon the addon object created by detailsFramework:CreateNewAddOn()
|
||||
---@return table
|
||||
@@ -83,7 +93,7 @@ end
|
||||
|
||||
---@param addonObject df_addon the addon object created by detailsFramework:CreateNewAddOn()
|
||||
---@param profileName profilename the name of the profile to set
|
||||
---@param bCopyFromCurrentProfile boolean if true, copy the current profile to the new profile
|
||||
---@param bCopyFromCurrentProfile boolean? if true, copy the current profile to the new profile
|
||||
function detailsFramework.SavedVars.SetProfile(addonObject, profileName, bCopyFromCurrentProfile)
|
||||
assert(type(addonObject) == "table", "SetProfile: addonObject must be a table.")
|
||||
assert(type(profileName) == "string", "SetProfile: profileName must be a string.")
|
||||
@@ -137,4 +147,147 @@ function detailsFramework.SavedVars.SaveProfile(addonObject)
|
||||
savedVariables.profiles[playerProfileId] = profileTable
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@class df_profilepanel : frame
|
||||
---@field AddonObject df_addon
|
||||
---@field ProfileNameValueLabel fontstring
|
||||
---@field ProfileSelectionDropdown df_dropdown
|
||||
---@field ProfileNameTextEntry df_textentry
|
||||
---@field OnClickCreateNewProfile function
|
||||
---@field RefreshSelectProfileDropdown function
|
||||
|
||||
---@param profilePanel df_profilepanel
|
||||
function detailsFramework.SavedVars.RefreshProfilePanel(profilePanel)
|
||||
local addonObject = profilePanel.AddonObject
|
||||
|
||||
--update the current profile name
|
||||
---@type string
|
||||
local profileName = detailsFramework.SavedVars.GetCurrentProfileName(addonObject)
|
||||
profilePanel.ProfileNameValueLabel:SetText(profileName)
|
||||
|
||||
--update the options of the dropdown to select a profile
|
||||
profilePanel:RefreshSelectProfileDropdown()
|
||||
|
||||
--clear the text entry for the new profile name
|
||||
profilePanel.ProfileNameTextEntry:SetText("")
|
||||
end
|
||||
|
||||
local profilePanelMixin = {
|
||||
---@param self df_profilepanel
|
||||
RefreshSelectProfileDropdown = function(self)
|
||||
local addonObject = self.AddonObject
|
||||
local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject)
|
||||
local profiles = savedVariables.profiles
|
||||
|
||||
local callback = function(self, fixedValue, profileSelected)
|
||||
detailsFramework.SavedVars.SetProfile(addonObject, profileSelected)
|
||||
detailsFramework.SavedVars.RefreshProfilePanel(self:GetParent())
|
||||
end
|
||||
|
||||
local dropdownOptions = {}
|
||||
for profileId in pairs(profiles) do
|
||||
table.insert(dropdownOptions, {value = profileId, label = profileId, onclick = callback, icon = [[Interface\CHATFRAME\UI-ChatIcon-BlizzardArcadeCollection]], iconsize = {16, 16}})
|
||||
end
|
||||
|
||||
self.ProfileSelectionDropdown.Options = dropdownOptions
|
||||
self.ProfileSelectionDropdown:Refresh()
|
||||
self.ProfileSelectionDropdown:Select(detailsFramework.SavedVars.GetCurrentProfileName(addonObject))
|
||||
end,
|
||||
|
||||
---@param self df_profilepanel
|
||||
OnClickCreateNewProfile = function(self)
|
||||
local addonObject = self.AddonObject
|
||||
local profileName = self.ProfileNameTextEntry:GetText()
|
||||
detailsFramework.SavedVars.SetProfile(addonObject, profileName)
|
||||
detailsFramework.SavedVars.RefreshProfilePanel(self)
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
local defaultProfilePanelOptions = {
|
||||
width = 600,
|
||||
height = 400,
|
||||
title = "Profile Management"
|
||||
}
|
||||
|
||||
function detailsFramework.SavedVars.CreateProfilePanel(addonObject, frameName, parentFrame, options)
|
||||
options = options or detailsFramework.table.copy({}, defaultProfilePanelOptions)
|
||||
detailsFramework.table.deploy(options, defaultProfilePanelOptions)
|
||||
|
||||
local textentryTemplate, labelTemplate = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"), detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local buttonTemplate = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
local dropdownTemplate = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
|
||||
--create a simple frame
|
||||
local panelOptions = {}
|
||||
---@type df_profilepanel
|
||||
local frame = CreateFrame("frame", frameName, parentFrame)
|
||||
frame:SetSize(options.width, options.height)
|
||||
frame.AddonObject = addonObject
|
||||
|
||||
detailsFramework:Mixin(frame, profilePanelMixin)
|
||||
detailsFramework:AddRoundedCornersToFrame(frame, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
|
||||
--create a label with the name of the profile (two labels, one for the name "Profile Name" and one for the value)
|
||||
---@type fontstring
|
||||
local profileNameLabel = frame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
profileNameLabel:SetPoint("topleft", frame, "topleft", 10, -10)
|
||||
profileNameLabel:SetText("Current Profile:")
|
||||
|
||||
---@type fontstring
|
||||
local profileNameValueLabel = frame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
profileNameValueLabel:SetPoint("left", profileNameLabel, "right", 5, 0)
|
||||
profileNameValueLabel:SetText("")
|
||||
frame.ProfileNameValueLabel = profileNameValueLabel
|
||||
|
||||
---@type fontstring
|
||||
local selectProfileLabel = frame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
selectProfileLabel:SetPoint("topleft", profileNameLabel, "bottomleft", 0, -15)
|
||||
selectProfileLabel:SetText("Select:")
|
||||
|
||||
--create a dropdown to select the profile
|
||||
local onSelectProfileCallback = function()
|
||||
return frame.ProfileSelectionDropdown.Options or {}
|
||||
end
|
||||
|
||||
local defaultValue = 1 -- set default to 1, latter when refreshing the entire panel, set the default to the current profile
|
||||
---@type df_dropdown
|
||||
local profileSelectionDropdown = detailsFramework:CreateDropDown(frame, onSelectProfileCallback, defaultValue, 180, 32, "ProfileSelectionDropdown", "$parentProfileSelectionDropdown", dropdownTemplate)
|
||||
profileSelectionDropdown:SetPoint("topleft", selectProfileLabel, "bottomleft", 0, -5)
|
||||
profileSelectionDropdown:SetBackdrop(nil)
|
||||
detailsFramework:AddRoundedCornersToFrame(profileSelectionDropdown, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
frame.ProfileSelectionDropdown = profileSelectionDropdown
|
||||
|
||||
---@type fontstring
|
||||
local createNewProfileLabel = frame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
createNewProfileLabel:SetPoint("topleft", profileSelectionDropdown.widget, "bottomleft", 0, -10)
|
||||
createNewProfileLabel:SetText("Create New:")
|
||||
|
||||
--create a textentry to enter the name of the profile to be created and create a button to create the new profile
|
||||
local onPressEnterCallback = function()
|
||||
|
||||
end
|
||||
|
||||
---@type df_textentry
|
||||
local profileNameTextEntry = detailsFramework:CreateTextEntry(frame, onPressEnterCallback, 180, 32, "ProfileNameEntry", "$parentProfileNameTextEntry", "Profile Name")
|
||||
profileNameTextEntry:SetPoint("topleft", createNewProfileLabel, "bottomleft", 0, -5)
|
||||
profileNameTextEntry:SetBackdrop(nil)
|
||||
profileNameTextEntry:SetJustifyH("left")
|
||||
profileNameTextEntry.fontsize = 12
|
||||
detailsFramework:AddRoundedCornersToFrame(profileNameTextEntry, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
frame.ProfileNameTextEntry = profileNameTextEntry
|
||||
|
||||
---@type df_button
|
||||
local createProfileButton = detailsFramework:CreateButton(frame, function() frame.OnClickCreateNewProfile(frame) end, 100, 32, "Create", false, false, false, "ProfileCreateButton", "$parentCreateProfileButton", buttonTemplate, labelTemplate)
|
||||
createProfileButton:SetPoint("left", profileNameTextEntry, "right", 5, 0)
|
||||
detailsFramework:AddRoundedCornersToFrame(createProfileButton, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
|
||||
frame:SetScript("OnShow", function()
|
||||
detailsFramework.SavedVars.RefreshProfilePanel(frame)
|
||||
end)
|
||||
|
||||
frame:Hide()
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
+15
-12
@@ -8,6 +8,8 @@ local C_Timer = _G.C_Timer
|
||||
local unpack = table.unpack or _G.unpack
|
||||
local GetTime = GetTime
|
||||
|
||||
local CONST_DEBUG_ENABLED = false
|
||||
|
||||
--make a namespace for schedules
|
||||
detailsFramework.Schedules = detailsFramework.Schedules or {}
|
||||
|
||||
@@ -67,10 +69,11 @@ local triggerScheduledLoop = function(tickerObject)
|
||||
local payload = tickerObject.payload
|
||||
local callback = tickerObject.callback
|
||||
|
||||
local result, errortext = pcall(callback, unpack(payload))
|
||||
if (not result) then
|
||||
detailsFramework:Msg("error on scheduler: ",tickerObject.path , tickerObject.name, errortext)
|
||||
end
|
||||
--local result, errortext = pcall(callback, unpack(payload))
|
||||
local runOkay, result = xpcall(callback, geterrorhandler(), unpack(payload))
|
||||
--if (not result) then
|
||||
-- detailsFramework:Msg("error on scheduler: ",tickerObject.path , tickerObject.name, errortext)
|
||||
--end
|
||||
|
||||
local checkPointCallback = tickerObject.checkPointCallback
|
||||
if (checkPointCallback) then
|
||||
@@ -127,10 +130,11 @@ local triggerScheduledTick = function(tickerObject)
|
||||
local payload = tickerObject.payload
|
||||
local callback = tickerObject.callback
|
||||
|
||||
local result, errortext = pcall(callback, unpack(payload))
|
||||
if (not result) then
|
||||
detailsFramework:Msg("error on scheduler: ",tickerObject.path , tickerObject.name, errortext)
|
||||
end
|
||||
local runOkay, result = xpcall(callback, geterrorhandler(), unpack(payload))
|
||||
--local result, errortext = pcall(callback, unpack(payload))
|
||||
--if (not result) then
|
||||
-- detailsFramework:Msg("error on scheduler: ",tickerObject.path , tickerObject.name, errortext)
|
||||
--end
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -142,8 +146,8 @@ function detailsFramework.Schedules.NewTicker(time, callback, ...)
|
||||
newTicker.callback = callback
|
||||
|
||||
--debug
|
||||
newTicker.path = debugstack()
|
||||
--
|
||||
newTicker.path = CONST_DEBUG_ENABLED and debugstack() or ""
|
||||
|
||||
return newTicker
|
||||
end
|
||||
|
||||
@@ -156,8 +160,7 @@ function detailsFramework.Schedules.NewTimer(time, callback, ...)
|
||||
newTimer.expireAt = GetTime() + time
|
||||
|
||||
--debug
|
||||
newTimer.path = debugstack()
|
||||
--
|
||||
newTimer.path = CONST_DEBUG_ENABLED and debugstack() or ""
|
||||
|
||||
return newTimer
|
||||
end
|
||||
|
||||
@@ -26,10 +26,12 @@ detailsFramework.ScrollBoxFunctions = {
|
||||
Refresh = function(self)
|
||||
--hide all frames and tag as not in use
|
||||
self._LinesInUse = 0
|
||||
--self.Frames has a list of frames used by the scrollbox
|
||||
for index, frame in ipairs(self.Frames) do
|
||||
if (not self.DontHideChildrenOnPreRefresh) then
|
||||
frame:Hide()
|
||||
end
|
||||
--set the frame as not in use
|
||||
frame._InUse = nil
|
||||
end
|
||||
|
||||
@@ -39,6 +41,7 @@ detailsFramework.ScrollBoxFunctions = {
|
||||
offset = self:GetOffsetFaux()
|
||||
end
|
||||
|
||||
--before starting the refresh, check if there's a pre refresh function and call it
|
||||
if (self.pre_refresh_func) then
|
||||
detailsFramework:Dispatch(self.pre_refresh_func, self, self.data, offset, self.LineAmount)
|
||||
end
|
||||
@@ -428,6 +431,24 @@ function detailsFramework:CreateGridScrollBox(parent, name, refreshFunc, data, c
|
||||
return scrollBox
|
||||
end
|
||||
|
||||
function detailsFramework.CreateRoundedOptionsScrollBox(parent, name, onRefreshButton, onSelectOption, tbdData, createSelectorButton, gridScrollBoxOptions)
|
||||
---when the scroll is refreshing the line, the line will call this function for each selection button on it
|
||||
---@param button df_button
|
||||
---@param data table
|
||||
local refreshAuraSelectorFrame = function(button, data)
|
||||
button.data = data
|
||||
|
||||
if (data.tooltip) then
|
||||
button.tooltip = data.tooltip
|
||||
end
|
||||
|
||||
xpcall(onRefreshButton, geterrorhandler(), button, data)
|
||||
|
||||
--set what happen when the user clicks the button
|
||||
button:SetClickFunction(onSelectOption, button, data)
|
||||
end
|
||||
end
|
||||
|
||||
--Need to test this and check the "same_name_spells_add(value)" on the OnEnter function
|
||||
--also need to make sure this can work with any data (global, class, spec) and aura type (buff, debuff)
|
||||
|
||||
|
||||
@@ -148,6 +148,10 @@ detailsFramework.TextEntryCounter = detailsFramework.TextEntryCounter or 1
|
||||
end
|
||||
end
|
||||
|
||||
local smember_fontsize = function(object, value)
|
||||
return detailsFramework:SetFontSize(object.editbox, value)
|
||||
end
|
||||
|
||||
--text horizontal pos
|
||||
local smember_horizontalpos = function(object, value)
|
||||
return object.editbox:SetJustifyH(string.lower(value))
|
||||
@@ -162,6 +166,8 @@ detailsFramework.TextEntryCounter = detailsFramework.TextEntryCounter or 1
|
||||
TextEntryMetaFunctions.SetMembers["text"] = smember_text
|
||||
TextEntryMetaFunctions.SetMembers["multiline"] = smember_multiline
|
||||
TextEntryMetaFunctions.SetMembers["align"] = smember_horizontalpos
|
||||
TextEntryMetaFunctions.SetMembers["fontsize"] = smember_fontsize
|
||||
TextEntryMetaFunctions.SetMembers["textsize"] = smember_fontsize
|
||||
|
||||
TextEntryMetaFunctions.__newindex = function(object, key, value)
|
||||
local func = TextEntryMetaFunctions.SetMembers[key]
|
||||
@@ -544,6 +550,7 @@ end
|
||||
---@field text any
|
||||
---@field multiline any
|
||||
---@field align any
|
||||
---@field fontsize any
|
||||
---@field ShouldOptimizeAutoComplete boolean?
|
||||
---@field SetTemplate fun(self:df_textentry, template:table)
|
||||
---@field Disable fun(self:df_textentry)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -374,21 +374,24 @@ function openRaidLib.GearManager.GetPlayerGemsAndEnchantInfo()
|
||||
end
|
||||
|
||||
--gems
|
||||
local itemStatsTable = {}
|
||||
--local itemStatsTable = {}
|
||||
--fill the table above with information about the item
|
||||
GetItemStats(itemLink, itemStatsTable)
|
||||
--GetItemStats(itemLink, itemStatsTable) --deprecated in 10.2.5
|
||||
local itemStatsTable = C_Item.GetItemStats(itemLink)
|
||||
|
||||
--check if the item has a socket
|
||||
if (itemStatsTable.EMPTY_SOCKET_PRISMATIC) then
|
||||
--check if the socket is empty
|
||||
for i = 1, itemStatsTable.EMPTY_SOCKET_PRISMATIC do
|
||||
local gemId = tonumber(gemsIds[i])
|
||||
if (not gemId or gemId == 0) then
|
||||
slotsWithoutGems[#slotsWithoutGems+1] = equipmentSlotId
|
||||
if (itemStatsTable) then
|
||||
if (itemStatsTable.EMPTY_SOCKET_PRISMATIC) then
|
||||
--check if the socket is empty
|
||||
for i = 1, itemStatsTable.EMPTY_SOCKET_PRISMATIC do
|
||||
local gemId = tonumber(gemsIds[i])
|
||||
if (not gemId or gemId == 0) then
|
||||
slotsWithoutGems[#slotsWithoutGems+1] = equipmentSlotId
|
||||
|
||||
--check if the gem is not a valid gem (deprecated gem)
|
||||
elseif (gemId < 180000) then
|
||||
slotsWithoutGems[#slotsWithoutGems+1] = equipmentSlotId
|
||||
--check if the gem is not a valid gem (deprecated gem)
|
||||
elseif (gemId < 180000) then
|
||||
slotsWithoutGems[#slotsWithoutGems+1] = equipmentSlotId
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -404,7 +407,7 @@ function openRaidLib.GearManager.BuildPlayerEquipmentList()
|
||||
for equipmentSlotId = 1, 17 do
|
||||
local itemLink = GetInventoryItemLink("player", equipmentSlotId)
|
||||
if (itemLink) then
|
||||
local itemStatsTable = {}
|
||||
--local itemStatsTable = {}
|
||||
local itemID, enchantID, gemID1, gemID2, gemID3, gemID4, suffixID, uniqueID, linkLevel, specializationID, modifiersMask, itemContext = select(2, strsplit(":", itemLink))
|
||||
itemID = tonumber(itemID)
|
||||
|
||||
@@ -415,7 +418,8 @@ function openRaidLib.GearManager.BuildPlayerEquipmentList()
|
||||
openRaidLib.__errors[#openRaidLib.__errors+1] = "Fail to get Item Level: " .. (itemID or "invalid itemID") .. " " .. (itemLink and itemLink:gsub("|H", "") or "invalid itemLink")
|
||||
end
|
||||
|
||||
GetItemStats(itemLink, itemStatsTable)
|
||||
local itemStatsTable = C_Item.GetItemStats(itemLink)
|
||||
--GetItemStats(itemLink, itemStatsTable)
|
||||
local gemSlotsAvailable = itemStatsTable and itemStatsTable.EMPTY_SOCKET_PRISMATIC or 0
|
||||
|
||||
local noPrefixItemLink = itemLink : gsub("^|c%x%x%x%x%x%x%x%x|Hitem", "")
|
||||
|
||||
@@ -376,6 +376,7 @@ do
|
||||
[115750] = {cooldown = 90, duration = 6, specs = {65, 66, 70}, talent = false, charges = 1, class = "PALADIN", type = 8}, --Blinding Light
|
||||
[231895] = {cooldown = 120, duration = 25, specs = {70}, talent = false, charges = 1, class = "PALADIN", type = 1}, --Crusade
|
||||
[498] = {cooldown = 60, duration = 8, specs = {65}, talent = false, charges = 1, class = "PALADIN", type = 2}, --Divine Protection
|
||||
[403876] = {cooldown = 60, duration = 8, specs = {65}, talent = false, charges = 1, class = "PALADIN", type = 2}, --Divine Protection Retribution
|
||||
[642] = {cooldown = 300, duration = 8, specs = {65, 66, 70}, talent = false, charges = 1, class = "PALADIN", type = 2}, --Divine Shield
|
||||
[205191] = {cooldown = 60, duration = 10, specs = {70}, talent = false, charges = 1, class = "PALADIN", type = 2}, --Eye for an Eye
|
||||
[86659] = {cooldown = 300, duration = 8, specs = {66}, talent = false, charges = 1, class = "PALADIN", type = 2}, --Guardian of Ancient Kings
|
||||
|
||||
Reference in New Issue
Block a user