You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1547 lines
66 KiB
1547 lines
66 KiB
|
|
local detailsFramework = _G["DetailsFramework"]
|
|
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
|
return
|
|
end
|
|
|
|
local unpack = unpack
|
|
local C_Timer = C_Timer
|
|
local InCombatLockdown = InCombatLockdown
|
|
local CreateFrame = CreateFrame
|
|
local PixelUtil = PixelUtil
|
|
local _
|
|
|
|
---@class df_menu_table : table
|
|
---@field text_template table
|
|
---@field id string an unique string or number to identify the button, from parent.widgetids[id], parent is the first argument of BuildMenu and BuildMenuVolatile
|
|
---@field namePhraseId string the phrase id (from language localization) to use on the button
|
|
|
|
---@class df_menu_label : df_menu_table
|
|
---@field get function
|
|
---@field color table
|
|
---@field font string
|
|
---@field size number
|
|
---@field text string
|
|
|
|
---@class df_menu_dropdown : df_menu_table
|
|
---@field type string
|
|
---@field set function
|
|
---@field get function
|
|
---@field values table
|
|
---@field name string
|
|
---@field desc string
|
|
---@field descPhraseId string
|
|
---@field hooks table
|
|
|
|
---@class df_menu_toggle : df_menu_table
|
|
---@field set function
|
|
---@field get function
|
|
---@field name string
|
|
---@field desc string
|
|
---@field descPhraseId string
|
|
---@field hooks table
|
|
---@field width number
|
|
---@field height number
|
|
---@field boxfirst boolean
|
|
|
|
---@class df_menu_range : df_menu_table
|
|
---@field set function
|
|
---@field get function
|
|
---@field min number
|
|
---@field max number
|
|
---@field step number
|
|
---@field name string
|
|
---@field desc string
|
|
---@field descPhraseId string
|
|
---@field hooks table
|
|
---@field thumbscale number
|
|
---@field usedecimals boolean if true allow fraction values
|
|
|
|
---@class df_menu_color : df_menu_table
|
|
---@field set function
|
|
---@field get function
|
|
---@field name string
|
|
---@field desc string
|
|
---@field descPhraseId string
|
|
---@field hooks table
|
|
---@field boxfirst boolean
|
|
|
|
---@class df_menu_button : df_menu_table
|
|
---@field func function the function to execute when the button is pressed
|
|
---@field param1 any the first parameter to pass to the function
|
|
---@field param2 any the second parameter to pass to the function
|
|
---@field name string text to show on the button
|
|
---@field desc string text to show on the tooltip
|
|
---@field descPhraseId string the phrase id (from language localization) to use on the tooltip
|
|
---@field hooks table a table with hooks to add to the button
|
|
---@field width number
|
|
---@field height number
|
|
---@field inline boolean
|
|
---@field icontexture any
|
|
---@field icontexcoords table
|
|
|
|
---@class df_menu_textentry : df_menu_table
|
|
---@field func function the function to execute when enter key is pressed
|
|
---@field set function same as above 'func'
|
|
---@field get function
|
|
---@field name string text to show on the button
|
|
---@field desc string text to show on the tooltip
|
|
---@field descPhraseId string the phrase id (from language localization) to use on the tooltip
|
|
---@field hooks table a table with hooks to add to the button
|
|
---@field inline boolean if true, the widget is placed in the rigt side of the previous one
|
|
---@field align string "left", "center" or "right"
|
|
---@field nocombat boolean can't edit when in combat
|
|
---@field spacement boolean gives a little of more space from the next widget
|
|
|
|
local onEnterHighlight = function(self)
|
|
self.highlightTexture:Show()
|
|
if (self.parent:GetScript("OnEnter")) then
|
|
self.parent:GetScript("OnEnter")(self.parent)
|
|
end
|
|
end
|
|
|
|
local onLeaveHighlight = function(self)
|
|
self.highlightTexture:Hide()
|
|
if (self.parent:GetScript("OnLeave")) then
|
|
self.parent:GetScript("OnLeave")(self.parent)
|
|
end
|
|
end
|
|
|
|
local createOptionHighlightTexture = function(frame, label, widgetWidth)
|
|
frame = frame.widget or frame
|
|
label = label.widget or label
|
|
|
|
local highlightFrame = CreateFrame("frame", nil, frame)
|
|
highlightFrame:EnableMouse(true)
|
|
highlightFrame:SetFrameLevel(frame:GetFrameLevel()-1)
|
|
|
|
PixelUtil.SetSize(highlightFrame, widgetWidth, frame:GetHeight() + 1)
|
|
PixelUtil.SetPoint(highlightFrame, "topleft", label, "topleft", -2, 5)
|
|
|
|
highlightFrame:SetScript("OnEnter", onEnterHighlight)
|
|
highlightFrame:SetScript("OnLeave", onLeaveHighlight)
|
|
|
|
local highlightTexture = highlightFrame:CreateTexture(nil, "overlay")
|
|
highlightTexture:SetColorTexture(1, 1, 1, 0.1)
|
|
PixelUtil.SetPoint(highlightTexture, "topleft", highlightFrame, "topleft", 0, 0)
|
|
PixelUtil.SetPoint(highlightTexture, "bottomright", highlightFrame, "bottomright", 0, 0)
|
|
highlightTexture:Hide()
|
|
|
|
local backgroundTexture = highlightFrame:CreateTexture(nil, "artwork")
|
|
backgroundTexture:SetColorTexture(1, 1, 1)
|
|
backgroundTexture:SetVertexColor(.25, .25, .25, 0.5)
|
|
PixelUtil.SetPoint(backgroundTexture, "topleft", highlightFrame, "topleft", 0, 0)
|
|
PixelUtil.SetPoint(backgroundTexture, "bottomright", highlightFrame, "bottomright", 0, 0)
|
|
|
|
highlightFrame.highlightTexture = highlightTexture
|
|
highlightFrame.parent = frame
|
|
|
|
return highlightTexture
|
|
end
|
|
|
|
|
|
|
|
local formatOptionNameWithColon = function(text, useColon)
|
|
if (text) then
|
|
if (useColon) then
|
|
text = text .. ":"
|
|
return text
|
|
else
|
|
return text
|
|
end
|
|
end
|
|
end
|
|
|
|
local widgetsToDisableOnCombat = {}
|
|
|
|
local getMenuWidgetVolative = function(parent, widgetType, indexTable)
|
|
local widgetObject
|
|
|
|
if (widgetType == "label") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType], "overlay")
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "dropdown") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateDropDown(parent, function() return {} end, nil, 120, 18, nil, "$parentWidget" .. widgetType .. indexTable[widgetType])
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
|
|
else
|
|
widgetObject:ClearHooks()
|
|
widgetObject.hasLabel.text = ""
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "switch") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateSwitch(parent, nil, true, 20, 20, nil, nil, nil, "$parentWidget" .. widgetType .. indexTable[widgetType])
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
else
|
|
widgetObject:ClearHooks()
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "slider") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateSlider(parent, 120, 20, 1, 2, 1, 1, false, nil, "$parentWidget" .. widgetType .. indexTable[widgetType])
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
else
|
|
widgetObject:ClearHooks()
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "color") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateColorPickButton(parent, "$parentWidget" .. widgetType .. indexTable[widgetType], nil, function()end, 1)
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
else
|
|
widgetObject:ClearHooks()
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "button") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateButton(parent, function()end, 120, 18, "", nil, nil, nil, nil, "$parentWidget" .. widgetType .. indexTable[widgetType])
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
else
|
|
widgetObject:ClearHooks()
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
|
|
elseif (widgetType == "textentry") then
|
|
widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]]
|
|
if (not widgetObject) then
|
|
widgetObject = detailsFramework:CreateTextEntry(parent, function()end, 120, 18, nil, "$parentWidget" .. widgetType .. indexTable[widgetType])
|
|
widgetObject.hasLabel = detailsFramework:CreateLabel(parent, "", 10, "white", "", nil, "$parentWidget" .. widgetType .. indexTable[widgetType] .. "label", "overlay")
|
|
|
|
table.insert(parent.widget_list, widgetObject)
|
|
table.insert(parent.widget_list_by_type[widgetType], widgetObject)
|
|
else
|
|
widgetObject:ClearHooks()
|
|
end
|
|
indexTable[widgetType] = indexTable[widgetType] + 1
|
|
end
|
|
|
|
--if the widget is inside the no combat table, remove it
|
|
for i = 1, #widgetsToDisableOnCombat do
|
|
if (widgetsToDisableOnCombat[i] == widgetObject) then
|
|
table.remove(widgetsToDisableOnCombat, i)
|
|
break
|
|
end
|
|
end
|
|
|
|
return widgetObject
|
|
end
|
|
|
|
--get the description phrase from the language table or use the .desc or .deschraseid
|
|
local getDescPhraseText = function(languageTable, widgetTable)
|
|
local descPhraseId = languageTable and (languageTable[widgetTable.descPhraseId] or languageTable[widgetTable.desc])
|
|
return descPhraseId or widgetTable.descPhraseId or widgetTable.desc or widgetTable.name or "-?-"
|
|
end
|
|
|
|
local getNamePhraseID = function(widgetTable, languageAddonId, languageTable, bIgnoreEmbed)
|
|
if (widgetTable.namePhraseId) then
|
|
return widgetTable.namePhraseId
|
|
end
|
|
|
|
if (not languageTable) then
|
|
return
|
|
end
|
|
|
|
local keyName = widgetTable.name
|
|
|
|
if (widgetTable.type == "label" and widgetTable.get) then
|
|
local key = widgetTable.get()
|
|
if (key and type(key) == "string") then
|
|
keyName = key
|
|
end
|
|
end
|
|
|
|
--embed key is when the phraseId is inside a string surounded by @
|
|
local embedPhraseId = keyName:match("@(.-)@")
|
|
|
|
local hasValue = detailsFramework.Language.DoesPhraseIDExistsInDefaultLanguage(languageAddonId, embedPhraseId or keyName)
|
|
if (not hasValue) then
|
|
return
|
|
end
|
|
|
|
if (embedPhraseId and not bIgnoreEmbed) then
|
|
return embedPhraseId, true
|
|
else
|
|
return keyName
|
|
end
|
|
end
|
|
|
|
local getNamePhraseText = function(languageTable, widgetTable, useColon, languageAddonId)
|
|
local namePhraseId, bWasEmbed = getNamePhraseID(widgetTable, languageAddonId, languageTable)
|
|
local namePhrase = languageTable and (languageTable[namePhraseId] or languageTable[widgetTable.namePhraseId] or languageTable[widgetTable.name])
|
|
|
|
if (bWasEmbed and widgetTable.name) then
|
|
namePhrase = widgetTable.name:gsub("@" .. namePhraseId .. "@", namePhrase)
|
|
end
|
|
|
|
return namePhrase or formatOptionNameWithColon(widgetTable.name, useColon) or widgetTable.namePhraseId or widgetTable.name or "-?-"
|
|
end
|
|
|
|
--volatile menu can be called several times, each time all settings are reset and a new menu is built reusing the widgets
|
|
function detailsFramework:BuildMenuVolatile(parent, menuOptions, xOffset, yOffset, height, useColon, textTemplate, dropdownTemplate, switchTemplate, switchIsCheckbox, sliderTemplate, buttonTemplate, valueChangeHook)
|
|
if (not parent.widget_list) then
|
|
detailsFramework:SetAsOptionsPanel(parent)
|
|
end
|
|
detailsFramework:ClearOptionsPanel(parent)
|
|
|
|
local currentXOffset = xOffset or 0
|
|
local currentYOffset = yOffset or 0
|
|
local maxColumnWidth = 0
|
|
|
|
local latestInlineWidget
|
|
|
|
local widgetIndexes = {
|
|
label = 1,
|
|
dropdown = 1,
|
|
switch = 1,
|
|
slider = 1,
|
|
color = 1,
|
|
button = 1,
|
|
textentry = 1,
|
|
}
|
|
|
|
if (height and type(height) == "number") then
|
|
height = math.abs((height or parent:GetHeight()) - math.abs(yOffset) + 20)
|
|
height = height * -1
|
|
else
|
|
height = parent:GetHeight()
|
|
end
|
|
|
|
--normalize format types
|
|
for index, widgetTable in ipairs(menuOptions) do
|
|
if (widgetTable.type == "space") then
|
|
widgetTable.type = "blank"
|
|
|
|
elseif (widgetTable.type == "fontdropdown") then
|
|
widgetTable.type = "selectfont"
|
|
elseif (widgetTable.type == "colordropdown") then
|
|
widgetTable.type = "selectcolor"
|
|
elseif (widgetTable.type == "outlinedropdown") then
|
|
widgetTable.type = "selectoutline"
|
|
elseif (widgetTable.type == "anchordropdown") then
|
|
widgetTable.type = "selectanchor"
|
|
elseif (widgetTable.type == "dropdown") then
|
|
widgetTable.type = "select"
|
|
|
|
elseif (widgetTable.type == "switch") then
|
|
widgetTable.type = "toggle"
|
|
|
|
elseif (widgetTable.type == "slider") then
|
|
widgetTable.type = "range"
|
|
|
|
elseif (widgetTable.type == "button") then
|
|
widgetTable.type = "execute"
|
|
end
|
|
end
|
|
|
|
--catch some options added in the hash part of the menu table
|
|
local bUseBoxFirstOnAllWidgets = menuOptions.always_boxfirst
|
|
local bAlignAsPairs = menuOptions.align_as_pairs
|
|
local nAlignAsPairsLength = menuOptions.align_as_pairs_string_space or 160
|
|
local languageAddonId = menuOptions.language_addonId
|
|
local widgetWidth = menuOptions.widget_width
|
|
local widgetHeight = menuOptions.widget_height
|
|
local languageTable
|
|
|
|
if (languageAddonId) then
|
|
languageTable = DetailsFramework.Language.GetLanguageTable(languageAddonId)
|
|
end
|
|
|
|
for index, widgetTable in ipairs(menuOptions) do
|
|
if (not widgetTable.hidden) then
|
|
local widgetCreated
|
|
if (latestInlineWidget) then
|
|
if (not widgetTable.inline) then
|
|
latestInlineWidget = nil
|
|
currentYOffset = currentYOffset - 20
|
|
end
|
|
end
|
|
|
|
local extraPaddingY = 0
|
|
|
|
if (not widgetTable.novolatile) then
|
|
--step a line
|
|
if (widgetTable.type == "blank" or widgetTable.type == "space") then
|
|
--do nothing
|
|
|
|
elseif (widgetTable.type == "label" or widgetTable.type == "text") then
|
|
local label = getMenuWidgetVolative(parent, "label", widgetIndexes)
|
|
widgetCreated = label
|
|
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable)
|
|
local namePhrase = (languageTable and (languageTable[namePhraseId] or languageTable[widgetTable.namePhraseId] or languageTable[widgetTable.name])) or (widgetTable.get and widgetTable.get()) or widgetTable.text or (widgetTable.namePhraseId) or ""
|
|
label.text = namePhrase
|
|
label.color = widgetTable.color
|
|
|
|
if (widgetTable.font) then
|
|
label.fontface = widgetTable.font
|
|
end
|
|
|
|
if (widgetTable.text_template or textTemplate) then
|
|
label:SetTemplate(widgetTable.text_template or textTemplate)
|
|
else
|
|
label.fontsize = widgetTable.size or 10
|
|
end
|
|
|
|
label._get = widgetTable.get
|
|
label.widget_type = "label"
|
|
label:ClearAllPoints()
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids [widgetTable.id] = label
|
|
end
|
|
|
|
--dropdowns
|
|
elseif (widgetTable.type:find("select")) then
|
|
assert(widgetTable.get, "DetailsFramework:BuildMenu(): .get() not found in the widget table for 'select'")
|
|
local dropdown = getMenuWidgetVolative(parent, "dropdown", widgetIndexes)
|
|
widgetCreated = dropdown
|
|
|
|
if (widgetTable.type == "selectfont") then
|
|
local func = detailsFramework:CreateFontListGenerator(widgetTable.set)
|
|
dropdown:SetFunction(func)
|
|
|
|
elseif (widgetTable.type == "selectcolor") then
|
|
local func = detailsFramework:CreateColorListGenerator(widgetTable.set)
|
|
dropdown:SetFunction(func)
|
|
|
|
elseif (widgetTable.type == "selectanchor") then
|
|
local func = detailsFramework:CreateAnchorPointListGenerator(widgetTable.set)
|
|
dropdown:SetFunction(func)
|
|
|
|
elseif (widgetTable.type == "selectoutline") then
|
|
local func = detailsFramework:CreateOutlineListGenerator(widgetTable.set)
|
|
dropdown:SetFunction(func)
|
|
else
|
|
dropdown:SetFunction(widgetTable.values)
|
|
end
|
|
|
|
dropdown:Refresh()
|
|
dropdown:Select(widgetTable.get())
|
|
dropdown:SetTemplate(dropdownTemplate)
|
|
|
|
if (widgetWidth) then
|
|
dropdown:SetWidth(widgetWidth)
|
|
end
|
|
if (widgetHeight) then
|
|
dropdown:SetHeight(widgetHeight)
|
|
end
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
dropdown:SetTooltip(descPhrase)
|
|
dropdown._get = widgetTable.get
|
|
dropdown.widget_type = "select"
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
dropdown.hasLabel.text = namePhrase
|
|
|
|
dropdown.hasLabel:SetTemplate(widgetTable.text_template or textTemplate)
|
|
|
|
--as these are reused widgets, clean the previous point
|
|
dropdown:ClearAllPoints()
|
|
dropdown.hasLabel:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
dropdown.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
dropdown:SetPoint("left", dropdown.hasLabel, "left", nAlignAsPairsLength, 0)
|
|
else
|
|
dropdown:SetPoint("left", dropdown.hasLabel, "right", 2, 0)
|
|
dropdown.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
--global callback
|
|
if (valueChangeHook) then
|
|
dropdown:SetHook("OnOptionSelected", valueChangeHook)
|
|
end
|
|
|
|
--hook list (hook list is wiped when getting the widget)
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
dropdown:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = dropdown
|
|
end
|
|
|
|
local widgetTotalSize = dropdown.hasLabel.widget:GetStringWidth() + 140 + 4
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
--switchs
|
|
elseif (widgetTable.type == "toggle" or widgetTable.type == "switch") then
|
|
local switch = getMenuWidgetVolative(parent, "switch", widgetIndexes)
|
|
widgetCreated = switch
|
|
|
|
switch:SetValue(widgetTable.get())
|
|
switch:SetTemplate(switchTemplate)
|
|
switch:SetAsCheckBox() --it's always a checkbox on volatile menu
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
switch:SetTooltip(descPhrase)
|
|
switch._get = widgetTable.get
|
|
switch.widget_type = "toggle"
|
|
switch.OnSwitch = widgetTable.set
|
|
|
|
if (valueChangeHook) then
|
|
switch:SetHook("OnSwitch", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
switch:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.width) then
|
|
switch:SetWidth(widgetTable.width)
|
|
end
|
|
if (widgetTable.height) then
|
|
switch:SetHeight(widgetTable.height)
|
|
end
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
switch.hasLabel.text = namePhrase
|
|
switch.hasLabel:SetTemplate(widgetTable.text_template or textTemplate)
|
|
|
|
switch:ClearAllPoints()
|
|
switch.hasLabel:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
switch.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
switch:SetPoint("left", switch.hasLabel, "left", nAlignAsPairsLength, 0)
|
|
else
|
|
if (widgetTable.boxfirst or bUseBoxFirstOnAllWidgets) then
|
|
switch:SetPoint(currentXOffset, currentYOffset)
|
|
switch.hasLabel:SetPoint("left", switch, "right", 2)
|
|
|
|
local nextWidgetTable = menuOptions[index+1]
|
|
if (nextWidgetTable) then
|
|
if (nextWidgetTable.type ~= "blank" and nextWidgetTable.type ~= "breakline" and nextWidgetTable.type ~= "toggle" and nextWidgetTable.type ~= "color") then
|
|
extraPaddingY = 4
|
|
end
|
|
end
|
|
else
|
|
switch.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
switch:SetPoint("left", switch.hasLabel, "right", 2)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids [widgetTable.id] = switch
|
|
end
|
|
|
|
local widgetTotalSize = switch.hasLabel:GetStringWidth() + 32
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
--slider
|
|
elseif (widgetTable.type == "range" or widgetTable.type == "slider") then
|
|
local slider = getMenuWidgetVolative(parent, "slider", widgetIndexes)
|
|
widgetCreated = slider
|
|
|
|
if (widgetTable.usedecimals) then
|
|
slider.slider:SetValueStep(0.01)
|
|
else
|
|
slider.slider:SetValueStep(widgetTable.step or 1)
|
|
end
|
|
slider.useDecimals = widgetTable.usedecimals
|
|
|
|
slider.slider:SetMinMaxValues(widgetTable.min, widgetTable.max)
|
|
slider.slider:SetValue(widgetTable.get())
|
|
slider.ivalue = slider.slider:GetValue()
|
|
|
|
slider:SetTemplate(sliderTemplate)
|
|
|
|
if (widgetWidth) then
|
|
slider:SetWidth(widgetWidth)
|
|
end
|
|
if (widgetHeight) then
|
|
slider:SetHeight(widgetHeight)
|
|
end
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
slider:SetTooltip(descPhrase)
|
|
slider._get = widgetTable.get
|
|
slider.widget_type = "range"
|
|
slider:SetHook("OnValueChange", widgetTable.set)
|
|
|
|
if (valueChangeHook) then
|
|
slider:SetHook("OnValueChange", valueChangeHook)
|
|
end
|
|
|
|
if (widgetTable.thumbscale) then
|
|
slider:SetThumbSize (slider.thumb.originalWidth * widgetTable.thumbscale, nil)
|
|
else
|
|
slider:SetThumbSize (slider.thumb.originalWidth * 1.3, nil)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
slider:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
slider.hasLabel.text = namePhrase
|
|
slider.hasLabel:SetTemplate(widgetTable.text_template or textTemplate)
|
|
|
|
slider:ClearAllPoints()
|
|
slider.hasLabel:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
slider.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
slider:SetPoint("left", slider.hasLabel, "left", nAlignAsPairsLength, 0)
|
|
else
|
|
slider:SetPoint("left", slider.hasLabel, "right", 2)
|
|
slider.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = slider
|
|
end
|
|
|
|
local widgetTotalSize = slider.hasLabel:GetStringWidth() + 146
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
--color
|
|
elseif (widgetTable.type == "color" or widgetTable.type == "color") then
|
|
local colorpick = getMenuWidgetVolative(parent, "color", widgetIndexes)
|
|
widgetCreated = colorpick
|
|
|
|
colorpick.color_callback = widgetTable.set --callback
|
|
colorpick:SetTemplate(buttonTemplate)
|
|
colorpick:SetSize(18, 18)
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
colorpick:SetTooltip(descPhrase)
|
|
colorpick._get = widgetTable.get
|
|
colorpick.widget_type = "color"
|
|
|
|
local default_value, g, b, a = widgetTable.get()
|
|
if (type(default_value) == "table") then
|
|
colorpick:SetColor(unpack(default_value))
|
|
else
|
|
colorpick:SetColor(default_value, g, b, a)
|
|
end
|
|
|
|
if (valueChangeHook) then
|
|
colorpick:SetHook("OnColorChanged", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
colorpick:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
local label = colorpick.hasLabel
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
label.text = namePhrase
|
|
label:SetTemplate(widgetTable.text_template or textTemplate)
|
|
|
|
label:ClearAllPoints()
|
|
colorpick:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
colorpick:SetPoint("left", label, "left", nAlignAsPairsLength, 0)
|
|
else
|
|
if (widgetTable.boxfirst or bUseBoxFirstOnAllWidgets) then
|
|
label:SetPoint("left", colorpick, "right", 2, 0)
|
|
colorpick:SetPoint(currentXOffset, currentYOffset)
|
|
extraPaddingY = 1
|
|
else
|
|
colorpick:SetPoint("left", label, "right", 2, 0)
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = colorpick
|
|
end
|
|
|
|
local widgetTotalSize = label:GetStringWidth() + 32
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
--button
|
|
elseif (widgetTable.type == "execute" or widgetTable.type == "button") then
|
|
local button = getMenuWidgetVolative(parent, "button", widgetIndexes)
|
|
widgetCreated = button
|
|
|
|
button:SetTemplate(buttonTemplate)
|
|
button:SetSize(widgetWidth or widgetTable.width or 120, widgetHeight or widgetTable.height or 18)
|
|
button:SetClickFunction(widgetTable.func, widgetTable.param1, widgetTable.param2)
|
|
|
|
local textTemplate = widgetTable.text_template or textTemplate or detailsFramework.font_templates["ORANGE_FONT_TEMPLATE"]
|
|
button.textcolor = textTemplate.color
|
|
button.textfont = textTemplate.font
|
|
button.textsize = textTemplate.size
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
button.text = namePhrase
|
|
|
|
button:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
button:SetPoint(currentXOffset, currentYOffset)
|
|
else
|
|
if (widgetTable.inline) then
|
|
if (latestInlineWidget) then
|
|
button:SetPoint("left", latestInlineWidget, "right", 2, 0)
|
|
latestInlineWidget = button
|
|
else
|
|
button:SetPoint(currentXOffset, currentYOffset)
|
|
latestInlineWidget = button
|
|
end
|
|
else
|
|
button:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
end
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
button:SetTooltip(descPhrase)
|
|
button.widget_type = "execute"
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
button:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.width) then
|
|
button:SetWidth(widgetTable.width)
|
|
end
|
|
if (widgetTable.height) then
|
|
button:SetHeight(widgetTable.height)
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = button
|
|
end
|
|
|
|
local widgetTotalSize = button:GetWidth() + 4
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
--textentry
|
|
elseif (widgetTable.type == "textentry") then
|
|
local textentry = getMenuWidgetVolative(parent, "textentry", widgetIndexes)
|
|
widgetCreated = textentry
|
|
|
|
textentry:SetCommitFunction(widgetTable.func or widgetTable.set)
|
|
textentry:SetTemplate(widgetTable.template or widgetTable.button_template or buttonTemplate)
|
|
textentry:SetSize(widgetWidth or widgetTable.width or 120, widgetHeight or widgetTable.height or 18)
|
|
|
|
local descPhrase = getDescPhraseText(languageTable, widgetTable)
|
|
textentry:SetTooltip(descPhrase)
|
|
textentry.text = widgetTable.get()
|
|
textentry._get = widgetTable.get
|
|
textentry.widget_type = "textentry"
|
|
|
|
textentry:SetHook("OnEnterPressed", function(...)
|
|
local upFunc = widgetTable.func or widgetTable.set
|
|
upFunc(...)
|
|
if (valueChangeHook) then
|
|
valueChangeHook()
|
|
end
|
|
end)
|
|
textentry:SetHook("OnEditFocusLost", function(...)
|
|
local upFunc = widgetTable.func or widgetTable.set
|
|
upFunc(...)
|
|
if (valueChangeHook) then
|
|
valueChangeHook()
|
|
end
|
|
end)
|
|
|
|
local namePhrase = getNamePhraseText(languageTable, widgetTable, useColon, languageAddonId)
|
|
textentry.hasLabel.text = namePhrase
|
|
textentry.hasLabel:SetTemplate(widgetTable.text_template or textTemplate)
|
|
|
|
textentry.hasLabel:ClearAllPoints()
|
|
textentry:ClearAllPoints()
|
|
|
|
if (bAlignAsPairs) then
|
|
textentry.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
textentry:SetPoint("left", textentry.hasLabel, "left", nAlignAsPairsLength, 0)
|
|
else
|
|
textentry:SetPoint("left", textentry.hasLabel, "right", 2)
|
|
textentry.hasLabel:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
textentry:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = textentry
|
|
end
|
|
|
|
local widgetTotalSize = textentry.hasLabel:GetStringWidth() + 64
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
end --end loop
|
|
|
|
if (widgetTable.nocombat) then
|
|
table.insert(widgetsToDisableOnCombat, widgetCreated)
|
|
end
|
|
|
|
if (not widgetTable.inline) then
|
|
if (widgetTable.spacement) then
|
|
currentYOffset = currentYOffset - 30
|
|
else
|
|
currentYOffset = currentYOffset - 20
|
|
end
|
|
end
|
|
|
|
if (extraPaddingY > 0) then
|
|
currentYOffset = currentYOffset - extraPaddingY
|
|
end
|
|
|
|
if (widgetTable.type == "breakline" or currentYOffset < height) then
|
|
currentYOffset = yOffset
|
|
currentXOffset = currentXOffset + maxColumnWidth + 20
|
|
maxColumnWidth = 0
|
|
end
|
|
|
|
if widgetCreated then
|
|
widgetCreated:Show()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
end
|
|
|
|
local getDescripttionPhraseID = function(widgetTable, languageAddonId, languageTable)
|
|
if (widgetTable.descPhraseId) then
|
|
return widgetTable.descPhraseId
|
|
end
|
|
|
|
if (not languageTable) then
|
|
return
|
|
end
|
|
|
|
local hasValue = detailsFramework.Language.DoesPhraseIDExistsInDefaultLanguage(languageAddonId, widgetTable.desc)
|
|
if (not hasValue) then
|
|
return
|
|
end
|
|
|
|
return widgetTable.desc
|
|
end
|
|
|
|
---classes used by the menu builder on the menuOptions table on both functions BuildMenu and BuildMenuVolatile
|
|
---the menuOptions consists of a table with several tables inside in array, each table is a widget to be created
|
|
---class df_menu_label is used when the sub table of menuOptions has a key named "type" with the value "label" or "text"
|
|
function detailsFramework:BuildMenu(parent, menuOptions, xOffset, yOffset, height, useColon, textTemplate, dropdownTemplate, switchTemplate, switchIsCheckbox, sliderTemplate, buttonTemplate, valueChangeHook)
|
|
--how many widgets has been created on this line loop pass
|
|
local amountLineWidgetCreated = 0
|
|
local latestInlineWidget
|
|
|
|
--normalize format types
|
|
for index, widgetTable in ipairs(menuOptions) do
|
|
if (widgetTable.type == "space") then
|
|
widgetTable.type = "blank"
|
|
|
|
elseif (widgetTable.type == "fontdropdown") then
|
|
widgetTable.type = "selectfont"
|
|
elseif (widgetTable.type == "colordropdown") then
|
|
widgetTable.type = "selectcolor"
|
|
elseif (widgetTable.type == "outlinedropdown") then
|
|
widgetTable.type = "selectoutline"
|
|
elseif (widgetTable.type == "anchordropdown") then
|
|
widgetTable.type = "selectanchor"
|
|
elseif (widgetTable.type == "dropdown") then
|
|
widgetTable.type = "select"
|
|
|
|
elseif (widgetTable.type == "switch") then
|
|
widgetTable.type = "toggle"
|
|
|
|
elseif (widgetTable.type == "slider") then
|
|
widgetTable.type = "range"
|
|
|
|
elseif (widgetTable.type == "button") then
|
|
widgetTable.type = "execute"
|
|
end
|
|
end
|
|
|
|
--catch some options added in the hash part of the menu table
|
|
local bUseBoxFirstOnAllWidgets = menuOptions.always_boxfirst
|
|
local widgetWidth = menuOptions.widget_width --a width to be used on all widgets
|
|
local widgetHeight = menuOptions.widget_height --a height to be used on all widgets
|
|
local bAlignAsPairs = menuOptions.align_as_pairs
|
|
local nAlignAsPairsLength = menuOptions.align_as_pairs_string_space or 160
|
|
local nAlignAsPairsSpacing = menuOptions.align_as_pairs_spacing or 20
|
|
|
|
--if a scrollbox is passed, the height can be ignored
|
|
--the scrollBox child will be used as the parent, and the height of the child will be resized to fit the widgets
|
|
local bUseScrollFrame = menuOptions.use_scrollframe
|
|
local biggestColumnHeight = 0 --used to resize the scrollbox child when a scrollbox is passed
|
|
|
|
if (not bUseScrollFrame) then
|
|
if (height and type(height) == "number") then
|
|
height = math.abs((height or parent:GetHeight()) - math.abs(yOffset) + 20)
|
|
height = height * -1
|
|
else
|
|
height = parent:GetHeight()
|
|
end
|
|
else
|
|
local width, height = parent:GetSize()
|
|
parent = parent:GetScrollChild()
|
|
parent:SetSize(width, height)
|
|
end
|
|
|
|
local languageAddonId = menuOptions.language_addonId
|
|
local languageTable
|
|
|
|
if (languageAddonId) then
|
|
languageTable = DetailsFramework.Language.GetLanguageTable(languageAddonId)
|
|
end
|
|
|
|
if (not parent.widget_list) then
|
|
detailsFramework:SetAsOptionsPanel(parent)
|
|
end
|
|
|
|
local currentXOffset = xOffset or 0
|
|
local currentYOffset = yOffset or 0
|
|
local maxColumnWidth = 0 --biggest width of widget + text size on the current column loop pass
|
|
local maxWidgetWidth = 0 --biggest widget width on the current column loop pass
|
|
local maxWidth = parent:GetWidth() --total width the buildmenu can use - not in use
|
|
|
|
for index, widgetTable in ipairs(menuOptions) do
|
|
if (not widgetTable.hidden) then
|
|
local widgetCreated
|
|
if (latestInlineWidget) then
|
|
if (not widgetTable.inline) then
|
|
latestInlineWidget = nil
|
|
currentYOffset = currentYOffset - 28
|
|
end
|
|
end
|
|
|
|
local extraPaddingY = 0
|
|
|
|
if (widgetTable.type == "blank") then
|
|
--do nothing
|
|
|
|
elseif (widgetTable.type == "label" or widgetTable.type == "text") then
|
|
---@cast widgetTable df_menu_label
|
|
|
|
local label = detailsFramework:CreateLabel(parent, "", widgetTable.text_template or textTemplate or widgetTable.size, widgetTable.color, widgetTable.font, nil, "$parentWidget" .. index, "overlay")
|
|
label._get = widgetTable.get
|
|
label.widget_type = "label"
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable)
|
|
if (namePhraseId) then
|
|
DetailsFramework.Language.RegisterObject(languageAddonId, label.widget, namePhraseId)
|
|
label.languageAddonId = languageAddonId
|
|
else
|
|
local textToSet = (widgetTable.get and widgetTable.get()) or widgetTable.text or ""
|
|
label:SetText(textToSet)
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, label)
|
|
table.insert(parent.widget_list_by_type.label, label)
|
|
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = label
|
|
end
|
|
|
|
elseif (widgetTable.type:find("select")) then
|
|
---@cast widgetTable df_menu_dropdown
|
|
|
|
assert(widgetTable.get, "DetailsFramework:BuildMenu(): .get not found in the widget table for 'select'")
|
|
|
|
local defaultHeight = 18
|
|
|
|
local dropdown
|
|
if (widgetTable.type == "selectfont") then
|
|
dropdown = detailsFramework:CreateFontDropDown(parent, widgetTable.set, widgetTable.get(), widgetWidth or 140, widgetHeight or defaultHeight, nil, "$parentWidget" .. index, dropdownTemplate)
|
|
|
|
elseif (widgetTable.type == "selectcolor") then
|
|
dropdown = detailsFramework:CreateColorDropDown(parent, widgetTable.set, widgetTable.get(), widgetWidth or 140, widgetHeight or defaultHeight, nil, "$parentWidget" .. index, dropdownTemplate)
|
|
|
|
elseif (widgetTable.type == "selectanchor") then
|
|
dropdown = detailsFramework:CreateAnchorPointDropDown(parent, widgetTable.set, widgetTable.get(), widgetWidth or 140, widgetHeight or defaultHeight, nil, "$parentWidget" .. index, dropdownTemplate)
|
|
|
|
elseif (widgetTable.type == "selectoutline") then
|
|
dropdown = detailsFramework:CreateOutlineDropDown(parent, widgetTable.set, widgetTable.get(), widgetWidth or 140, widgetHeight or defaultHeight, nil, "$parentWidget" .. index, dropdownTemplate)
|
|
else
|
|
dropdown = detailsFramework:NewDropDown(parent, nil, "$parentWidget" .. index, nil, widgetWidth or 140, widgetHeight or defaultHeight, widgetTable.values, widgetTable.get(), dropdownTemplate)
|
|
end
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, dropdown, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
dropdown._get = widgetTable.get
|
|
dropdown.widget_type = "select"
|
|
|
|
local label = detailsFramework:NewLabel(parent, nil, "$parentLabel" .. index, nil, "", "GameFontNormal", widgetTable.text_template or textTemplate or 12)
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, label.widget, namePhraseId, formatOptionNameWithColon(widgetTable.name, useColon))
|
|
|
|
dropdown.addonId = languageAddonId
|
|
if (languageAddonId) then
|
|
detailsFramework.Language.RegisterCallback(languageAddonId, function(addonId, languageId, ...) dropdown:Select(dropdown:GetValue()) end)
|
|
C_Timer.After(0.1, function() dropdown:Select(dropdown:GetValue()) end)
|
|
end
|
|
|
|
if (bAlignAsPairs) then
|
|
PixelUtil.SetPoint(label.widget, "topleft", dropdown:GetParent(), "topleft", currentXOffset, currentYOffset)
|
|
PixelUtil.SetPoint(dropdown.widget, "left", label.widget, "left", nAlignAsPairsLength, 0)
|
|
createOptionHighlightTexture(dropdown, label, (widgetWidth or 140) + nAlignAsPairsLength + 5)
|
|
else
|
|
dropdown:SetPoint("left", label, "right", 2, 0)
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
dropdown.hasLabel = label
|
|
|
|
--global callback
|
|
if (valueChangeHook) then
|
|
dropdown:SetHook("OnOptionSelected", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
dropdown:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = dropdown
|
|
end
|
|
|
|
local widgetTotalSize = label.widget:GetStringWidth() + 144
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (dropdown:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = dropdown:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, dropdown)
|
|
table.insert(parent.widget_list_by_type.dropdown, dropdown)
|
|
|
|
widgetCreated = dropdown
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
elseif (widgetTable.type == "toggle") then
|
|
---@cast widgetTable df_menu_toggle
|
|
|
|
local switch = detailsFramework:NewSwitch(parent, nil, "$parentWidget" .. index, nil, 60, 20, nil, nil, widgetTable.get(), nil, nil, nil, nil, switchTemplate)
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, switch, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
switch._get = widgetTable.get
|
|
switch.widget_type = "toggle"
|
|
switch.OnSwitch = widgetTable.set
|
|
|
|
if (switchIsCheckbox) then
|
|
switch:SetAsCheckBox()
|
|
end
|
|
|
|
if (valueChangeHook) then
|
|
switch:SetHook("OnSwitch", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
switch:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.width) then
|
|
PixelUtil.SetWidth(switch.widget, widgetTable.width)
|
|
end
|
|
if (widgetTable.height) then
|
|
PixelUtil.SetHeight(switch.widget, widgetTable.height)
|
|
end
|
|
|
|
local label = detailsFramework:NewLabel(parent, nil, "$parentLabel" .. index, nil, "", "GameFontNormal", widgetTable.text_template or textTemplate or 12)
|
|
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, label.widget, namePhraseId, formatOptionNameWithColon(widgetTable.name, useColon))
|
|
|
|
if (bAlignAsPairs) then
|
|
PixelUtil.SetPoint(label.widget, "topleft", switch:GetParent(), "topleft", currentXOffset, currentYOffset)
|
|
PixelUtil.SetPoint(switch.widget, "left", label.widget, "left", nAlignAsPairsLength, 0)
|
|
createOptionHighlightTexture(switch, label, (widgetWidth or 140) + nAlignAsPairsLength + 5)
|
|
else
|
|
if (widgetTable.boxfirst or bUseBoxFirstOnAllWidgets) then
|
|
switch:SetPoint(currentXOffset, currentYOffset)
|
|
label:SetPoint("left", switch, "right", 2)
|
|
|
|
local nextWidgetTable = menuOptions[index+1]
|
|
if (nextWidgetTable) then
|
|
if (nextWidgetTable.type ~= "blank" and nextWidgetTable.type ~= "breakline" and nextWidgetTable.type ~= "toggle" and nextWidgetTable.type ~= "color") then
|
|
extraPaddingY = 4
|
|
end
|
|
end
|
|
else
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
switch:SetPoint("left", label, "right", 2, 0)
|
|
end
|
|
end
|
|
switch.hasLabel = label
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = switch
|
|
end
|
|
|
|
local widgetTotalSize = label.widget:GetStringWidth() + 32
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (switch:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = switch:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, switch)
|
|
table.insert(parent.widget_list_by_type.switch, switch)
|
|
|
|
widgetCreated = switch
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
elseif (widgetTable.type == "range") then
|
|
---@cast widgetTable df_menu_range
|
|
|
|
assert(widgetTable.get, "DetailsFramework:BuildMenu(): .get not found in the widget table for 'range'")
|
|
local bIsDecimals = widgetTable.usedecimals
|
|
local slider = detailsFramework:NewSlider(parent, nil, "$parentWidget" .. index, nil, widgetWidth or 140, widgetHeight or 18, widgetTable.min, widgetTable.max, widgetTable.step, widgetTable.get(), bIsDecimals, nil, nil, sliderTemplate)
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, slider, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
slider._get = widgetTable.get
|
|
slider.widget_type = "range"
|
|
slider:SetHook("OnValueChange", widgetTable.set)
|
|
|
|
if (widgetTable.thumbscale) then
|
|
slider:SetThumbSize(slider.thumb:GetWidth() * widgetTable.thumbscale, nil)
|
|
else
|
|
slider:SetThumbSize(slider.thumb:GetWidth() * 1.3, nil)
|
|
end
|
|
|
|
if (valueChangeHook) then
|
|
slider:SetHook("OnValueChange", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
slider:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
local label = detailsFramework:NewLabel(parent, nil, "$parentLabel" .. index, nil, "", "GameFontNormal", widgetTable.text_template or textTemplate or 12)
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, label.widget, namePhraseId, formatOptionNameWithColon(widgetTable.name, useColon))
|
|
|
|
if (bAlignAsPairs) then
|
|
PixelUtil.SetPoint(label.widget, "topleft", slider:GetParent(), "topleft", currentXOffset, currentYOffset)
|
|
PixelUtil.SetPoint(slider.widget, "left", label.widget, "left", nAlignAsPairsLength, 0)
|
|
createOptionHighlightTexture(slider, label, (widgetWidth or 140) + nAlignAsPairsLength + 5)
|
|
else
|
|
slider:SetPoint("left", label, "right", 2)
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
slider.hasLabel = label
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = slider
|
|
end
|
|
|
|
local widgetTotalSize = label.widget:GetStringWidth() + 146
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (slider:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = slider:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, slider)
|
|
table.insert(parent.widget_list_by_type.slider, slider)
|
|
|
|
widgetCreated = slider
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
elseif (widgetTable.type == "color") then
|
|
---@cast widgetTable df_menu_color
|
|
assert(widgetTable.get, "DetailsFramework:BuildMenu(): .get not found in the widget table for 'color'")
|
|
local colorpick = detailsFramework:NewColorPickButton(parent, "$parentWidget" .. index, nil, widgetTable.set, nil, buttonTemplate)
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, colorpick, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
colorpick._get = widgetTable.get
|
|
colorpick.widget_type = "color"
|
|
colorpick:SetSize(18, 18)
|
|
|
|
local r, g, b, a = detailsFramework:ParseColors(widgetTable.get())
|
|
colorpick:SetColor(r, g, b, a)
|
|
|
|
if (valueChangeHook) then
|
|
colorpick:SetHook("OnColorChanged", valueChangeHook)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
colorpick:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
local label = detailsFramework:NewLabel(parent, nil, "$parentLabel" .. index, nil, "", "GameFontNormal", widgetTable.text_template or textTemplate or 12)
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, label.widget, namePhraseId, formatOptionNameWithColon(widgetTable.name, useColon))
|
|
|
|
if (bAlignAsPairs) then
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
colorpick:SetPoint("left", label, "left", nAlignAsPairsLength, 0)
|
|
createOptionHighlightTexture(colorpick, label, (widgetWidth or 140) + nAlignAsPairsLength + 5)
|
|
else
|
|
if (widgetTable.boxfirst or bUseBoxFirstOnAllWidgets) then
|
|
label:SetPoint("left", colorpick, "right", 2)
|
|
colorpick:SetPoint(currentXOffset, currentYOffset)
|
|
extraPaddingY = 1
|
|
else
|
|
colorpick:SetPoint("left", label, "right", 2)
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
end
|
|
|
|
colorpick.hasLabel = label
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids[widgetTable.id] = colorpick
|
|
end
|
|
|
|
local widgetTotalSize = label.widget:GetStringWidth() + 32
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (colorpick:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = colorpick:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, colorpick)
|
|
table.insert(parent.widget_list_by_type.color, colorpick)
|
|
|
|
widgetCreated = colorpick
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
elseif (widgetTable.type == "execute") then
|
|
---@cast widgetTable df_menu_button
|
|
|
|
local button = detailsFramework:NewButton(parent, nil, "$parentWidget" .. index, nil, widgetWidth or 120, widgetHeight or 18, widgetTable.func, widgetTable.param1, widgetTable.param2, nil, "", nil, buttonTemplate, textTemplate)
|
|
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, button.widget, namePhraseId, widgetTable.name)
|
|
|
|
if (not buttonTemplate) then
|
|
button:InstallCustomTexture()
|
|
end
|
|
|
|
if (widgetTable.inline) then
|
|
if (latestInlineWidget) then
|
|
button:SetPoint("left", latestInlineWidget, "right", 2, 0)
|
|
latestInlineWidget = button
|
|
else
|
|
button:SetPoint(currentXOffset, currentYOffset)
|
|
latestInlineWidget = button
|
|
end
|
|
else
|
|
button:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, button, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
button.widget_type = "execute"
|
|
|
|
--button icon
|
|
if (widgetTable.icontexture) then
|
|
button:SetIcon(widgetTable.icontexture, nil, nil, nil, widgetTable.icontexcoords, nil, nil, 2)
|
|
end
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
button:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids [widgetTable.id] = button
|
|
end
|
|
|
|
if (widgetTable.width and not widgetWidth) then
|
|
button:SetWidth(widgetTable.width)
|
|
end
|
|
if (widgetTable.height and not widgetHeight) then
|
|
button:SetHeight(widgetTable.height)
|
|
end
|
|
|
|
local widgetTotalSize = button:GetWidth() + 4
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (button:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = button:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, button)
|
|
table.insert(parent.widget_list_by_type.button, button)
|
|
|
|
widgetCreated = button
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
|
|
elseif (widgetTable.type == "textentry") then
|
|
---@cast widgetTable df_menu_textentry
|
|
|
|
local textentry = detailsFramework:CreateTextEntry(parent, widgetTable.func or widgetTable.set, widgetWidth or 120, widgetHeight or 18, nil, "$parentWidget" .. index, nil, buttonTemplate)
|
|
textentry.align = widgetTable.align or "left"
|
|
|
|
local descPhraseId = getDescripttionPhraseID(widgetTable, languageAddonId, languageTable)
|
|
DetailsFramework.Language.RegisterTableKeyWithDefault(languageAddonId, textentry, "have_tooltip", descPhraseId, widgetTable.desc)
|
|
|
|
textentry.text = widgetTable.get()
|
|
textentry._get = widgetTable.get
|
|
textentry.widget_type = "textentry"
|
|
textentry:SetHook("OnEnterPressed", widgetTable.func or widgetTable.set)
|
|
textentry:SetHook("OnEditFocusLost", widgetTable.func or widgetTable.set)
|
|
|
|
local label = detailsFramework:NewLabel(parent, nil, "$parentLabel" .. index, nil, "", "GameFontNormal", widgetTable.text_template or textTemplate or 12)
|
|
|
|
local namePhraseId = getNamePhraseID(widgetTable, languageAddonId, languageTable, true)
|
|
DetailsFramework.Language.RegisterObjectWithDefault(languageAddonId, label.widget, namePhraseId, formatOptionNameWithColon(widgetTable.name, useColon))
|
|
|
|
if (bAlignAsPairs) then
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
textentry:SetPoint("left", label, "left", nAlignAsPairsLength, 0)
|
|
createOptionHighlightTexture(textentry, label, (widgetWidth or 140) + nAlignAsPairsLength + 5)
|
|
else
|
|
textentry:SetPoint("left", label, "right", 2)
|
|
label:SetPoint(currentXOffset, currentYOffset)
|
|
end
|
|
|
|
textentry.hasLabel = label
|
|
|
|
--hook list
|
|
if (widgetTable.hooks) then
|
|
for hookName, hookFunc in pairs(widgetTable.hooks) do
|
|
textentry:SetHook(hookName, hookFunc)
|
|
end
|
|
end
|
|
|
|
if (widgetTable.id) then
|
|
parent.widgetids [widgetTable.id] = textentry
|
|
end
|
|
|
|
local widgetTotalSize = label.widget:GetStringWidth() + 64
|
|
if (widgetTotalSize > maxColumnWidth) then
|
|
maxColumnWidth = widgetTotalSize
|
|
end
|
|
|
|
if (textentry:GetWidth() > maxWidgetWidth) then
|
|
maxWidgetWidth = textentry:GetWidth()
|
|
end
|
|
|
|
--store the widget created into the overall table and the widget by type
|
|
table.insert(parent.widget_list, textentry)
|
|
table.insert(parent.widget_list_by_type.textentry, textentry)
|
|
|
|
widgetCreated = textentry
|
|
amountLineWidgetCreated = amountLineWidgetCreated + 1
|
|
end
|
|
|
|
if (widgetTable.nocombat) then
|
|
table.insert(widgetsToDisableOnCombat, widgetCreated)
|
|
end
|
|
|
|
if (not widgetTable.inline) then
|
|
if (widgetTable.spacement) then
|
|
currentYOffset = currentYOffset - 30
|
|
else
|
|
currentYOffset = currentYOffset - 20
|
|
end
|
|
end
|
|
|
|
if (extraPaddingY > 0) then
|
|
currentYOffset = currentYOffset - extraPaddingY
|
|
end
|
|
|
|
if (bUseScrollFrame) then
|
|
if (widgetTable.type == "breakline") then
|
|
biggestColumnHeight = math.min(currentYOffset, biggestColumnHeight)
|
|
currentYOffset = yOffset
|
|
|
|
if (bAlignAsPairs) then
|
|
currentXOffset = currentXOffset + nAlignAsPairsLength + (widgetWidth or maxWidgetWidth) + nAlignAsPairsSpacing
|
|
else
|
|
currentXOffset = currentXOffset + maxColumnWidth + 20
|
|
end
|
|
|
|
amountLineWidgetCreated = 0
|
|
maxColumnWidth = 0
|
|
maxWidgetWidth = 0
|
|
end
|
|
else
|
|
if (widgetTable.type == "breakline" or currentYOffset < height) then
|
|
currentYOffset = yOffset
|
|
currentXOffset = currentXOffset + maxColumnWidth + 20
|
|
amountLineWidgetCreated = 0
|
|
maxColumnWidth = 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (bUseScrollFrame) then
|
|
parent:SetHeight(biggestColumnHeight * -1)
|
|
end
|
|
|
|
detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
end
|
|
|
|
|
|
local lockNotSafeWidgetsForCombat = function()
|
|
for _, widget in ipairs(widgetsToDisableOnCombat) do
|
|
widget:Disable()
|
|
end
|
|
end
|
|
|
|
local unlockNotSafeWidgetsForCombat = function()
|
|
for _, widget in ipairs(widgetsToDisableOnCombat) do
|
|
widget:Enable()
|
|
end
|
|
end
|
|
|
|
function detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
if (detailsFramework.PlayerHasCombatFlag) then
|
|
lockNotSafeWidgetsForCombat()
|
|
else
|
|
unlockNotSafeWidgetsForCombat()
|
|
end
|
|
end
|
|
|
|
detailsFramework.PlayerHasCombatFlag = false
|
|
local ProtectCombatFrame = CreateFrame("frame")
|
|
ProtectCombatFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
ProtectCombatFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
ProtectCombatFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
ProtectCombatFrame:SetScript("OnEvent", function(self, event)
|
|
if (event == "PLAYER_ENTERING_WORLD") then
|
|
if (InCombatLockdown()) then
|
|
detailsFramework.PlayerHasCombatFlag = true
|
|
else
|
|
detailsFramework.PlayerHasCombatFlag = false
|
|
end
|
|
detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
|
|
elseif (event == "PLAYER_REGEN_ENABLED") then
|
|
detailsFramework.PlayerHasCombatFlag = false
|
|
detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
|
|
elseif (event == "PLAYER_REGEN_DISABLED") then
|
|
detailsFramework.PlayerHasCombatFlag = true
|
|
detailsFramework.RefreshUnsafeOptionsWidgets()
|
|
end
|
|
end)
|
|
|
|
function detailsFramework:CreateInCombatTexture(frame)
|
|
if (detailsFramework.debug and not frame) then
|
|
error("Details! Framework: CreateInCombatTexture invalid frame on parameter 1.")
|
|
end
|
|
|
|
local inCombatBackgroundTexture = detailsFramework:CreateImage(frame)
|
|
inCombatBackgroundTexture:SetColorTexture(.6, 0, 0, .1)
|
|
inCombatBackgroundTexture:Hide()
|
|
|
|
local inCombatLabel = detailsFramework:CreateLabel(frame, "you are in combat", 24, "silver")
|
|
inCombatLabel:SetPoint("right", inCombatBackgroundTexture, "right", -10, 0)
|
|
inCombatLabel:Hide()
|
|
|
|
frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
|
|
frame:SetScript("OnEvent", function(self, event)
|
|
if (event == "PLAYER_REGEN_DISABLED") then
|
|
inCombatBackgroundTexture:Show()
|
|
inCombatLabel:Show()
|
|
|
|
elseif (event == "PLAYER_REGEN_ENABLED") then
|
|
inCombatBackgroundTexture:Hide()
|
|
inCombatLabel:Hide()
|
|
end
|
|
end)
|
|
|
|
return inCombatBackgroundTexture
|
|
end
|