Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 76 additions & 31 deletions LibAddonMenu-2.0/LibAddonMenu-2.0.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@

local MAJOR, MINOR = "LibAddonMenu-2.0", _LAM2_VERSION_NUMBER or -1

---@alias Stringy SafeStringKey|string|fun():(string|nil) a string id, string, or function returning a string

---@class LAM2_ControlData
---@field type "button"|"checkbox"|"colorpicker"|"custom"|"description"|"divider"|"dropdown"|"editbox"|"header"|"iconpicker"|"panel"|"slider"|"submenu"|"texture"
---@field name nil|Stringy

---@class LAM2_ControlWithHelpUrlData: LAM2_ControlData
---@field helpUrl nil|Stringy ex. "https://www.esoui.com/portal.php?id=218&a=faq"

---@class LAM2_BaseControlData: LAM2_ControlData
---@field width nil|"full"|"half" default "full"
---@field reference nil|string a unique global reference to the created control ex. "MyAddonButton"

---@class LAM2_LabelAndContainerControlData: LAM2_BaseControlData, LAM2_ControlWithHelpUrlData
---@field tooltip nil|Stringy ex. "Button's tooltip text."
---@field tooltipText nil|string

---@class LAM2_Control: Control

---@class LAM2_ControlWithHelpUrl: LAM2_Control
---@field data LAM2_ControlWithHelpUrlData
---@field faqControl LAM2_FAQControl

local lam
if(not LibStub) then
lam = {}
Expand Down Expand Up @@ -42,6 +65,7 @@ else
logger = setmetatable({}, { __index = function() return noop end })
end

---@diagnostic disable-next-line: undefined-global
if LAMSettingsPanelCreated and not LAMCompatibilityWarning then
PrintLater("An old version of LibAddonMenu with compatibility issues was detected. For more information on how to proceed search for LibAddonMenu on esoui.com")
LAMCompatibilityWarning = true
Expand All @@ -64,6 +88,7 @@ local LAM_DEFAULTS_DIALOG = "LAM_DEFAULTS"
local LAM_RELOAD_DIALOG = "LAM_RELOAD_DIALOG"

local addonsForList = {}
---@type table<string, LAM2_ControlData[]>
local addonToOptionsMap = {}
local optionsState = {}
lam.widgets = lam.widgets or {}
Expand Down Expand Up @@ -100,12 +125,14 @@ local function GetColorForState(disabled)
return disabled and ZO_DEFAULT_DISABLED_COLOR or ZO_DEFAULT_ENABLED_COLOR
end

--- @param control LAM2_ControlWithHelpUrl
local function CreateFAQTexture(control)
local controlData = control.data
if not control or not controlData then logger:Warn("CreateFAQTexture - missing or invalid control") return end
local helpUrl = controlData and GetStringFromValue(controlData.helpUrl)
if not helpUrl or helpUrl == "" then return end

---@class LAM2_FAQControl: TextureControl
local faqControl = wm:CreateControl(nil, control, CT_TEXTURE)
control.faqControl = faqControl

Expand Down Expand Up @@ -144,7 +171,9 @@ local function CreateFAQTexture(control)
return faqControl
end

---@param controlData LAM2_BaseControlData
local function CreateBaseControl(parent, controlData, controlName)
---@class LAM2_BaseControl: LAM2_Control
local control = wm:CreateControl(controlName or controlData.reference, parent.scroll or parent, CT_CONTROL)
control.panel = parent.panel or parent -- if this is in a submenu, panel is the submenu's parent
control.data = controlData
Expand All @@ -156,7 +185,10 @@ local function CreateBaseControl(parent, controlData, controlName)
return control
end

---@param controlData LAM2_LabelAndContainerControlData
local function CreateLabelAndContainerControl(parent, controlData, controlName)
---@class LAM2_LabelAndContainerControl: LAM2_BaseControl
---@field data LAM2_LabelAndContainerControlData
local control = CreateBaseControl(parent, controlData, controlName)
local width = control:GetWidth()

Expand All @@ -172,7 +204,7 @@ local function CreateLabelAndContainerControl(parent, controlData, controlName)
control.labelContainer = container
end

local label = wm:CreateControl(nil, labelContainer or control, CT_LABEL)
local label = wm:CreateControl(nil, labelContainer or control, CT_LABEL) --[[@as LabelControl]]
label:SetFont("ZoFontWinH4")
label:SetHeight(MIN_HEIGHT)
label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
Expand Down Expand Up @@ -207,6 +239,15 @@ local function CreateLabelAndContainerControl(parent, controlData, controlName)
return control
end

---@class TooltipData
---@field tooltipText string

---@class ControlWithData: Control
---@field data TooltipData

---@param control ControlWithData
---@param data LAM2_LabelAndContainerControlData
---@param tooltipData TooltipData
local function SetUpTooltip(control, data, tooltipData)
if not data.tooltip then return end
control:SetMouseEnabled(true)
Expand Down Expand Up @@ -726,15 +767,15 @@ local function PopulateAddonList(addonList, filter)
end


--METHOD: REGISTER WIDGET--
--each widget has its version checked before loading,
--so we only have the most recent one in memory
--Usage:
-- widgetType = "string"; the type of widget being registered
-- widgetVersion = integer; the widget's version number

LAMCreateControl = LAMCreateControl or {}
local lamcc = LAMCreateControl

--METHOD: REGISTER WIDGET--
--each widget has its version checked before loading,
--so we only have the most recent one in memory
---@param widgetType string the type of widget being registered
---@param widgetVersion integer the widget's version number
function lam:RegisterWidget(widgetType, widgetVersion)
if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
return false
Expand Down Expand Up @@ -784,11 +825,10 @@ local function CloseCurrentPanel()
end
end

local locSettings = GetString(SI_GAME_MENU_SETTINGS)
--METHOD: OPEN TO ADDON PANEL--
--opens to a specific addon's option panel
--Usage:
-- panel = userdata; the panel returned by the :RegisterOptionsPanel method
local locSettings = GetString(SI_GAME_MENU_SETTINGS)
---@param panel LAM2_Panel the panel returned by the :RegisterOptionsPanel method
function lam:OpenToPanel(panel)

-- find and select the panel's row in addon list
Expand All @@ -808,7 +848,7 @@ function lam:OpenToPanel(panel)
ZO_ScrollList_SelectData(addonList, selectedData)
ZO_ScrollList_RefreshVisible(addonList, selectedData)

local srchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit")
local srchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit") --[[@as EditControl]]
srchEdit:Clear()

-- note that ZO_ScrollList doesn't require `selectedData` to be actually
Expand All @@ -817,7 +857,7 @@ function lam:OpenToPanel(panel)

local function openAddonSettingsMenu()
local gameMenu = ZO_GameMenu_InGame.gameMenu
local settingsMenu = gameMenu.headerControls[locSettings]
local settingsMenu = gameMenu.headerControls[locSettings] --[[@as ZO_TreeNode]]

if settingsMenu then -- an instance of ZO_TreeNode
local children = settingsMenu:GetChildren()
Expand All @@ -842,10 +882,13 @@ function lam:OpenToPanel(panel)
end

local TwinOptionsContainer_Index = 0
---@param leftWidget Control
---@param rightWidget Control
local function TwinOptionsContainer(parent, leftWidget, rightWidget)
TwinOptionsContainer_Index = TwinOptionsContainer_Index + 1
local cParent = parent.scroll or parent
local panel = parent.panel or cParent
---@class Container: Control
local container = wm:CreateControl("$(parent)TwinContainer" .. tostring(TwinOptionsContainer_Index),
cParent, CT_CONTROL)
container:SetResizeToFitDescendents(true)
Expand All @@ -869,6 +912,7 @@ end
--INTERNAL FUNCTION
--creates controls when options panel is first shown
--controls anchoring of these controls in the panel
---@param panel LAM2_Panel
local function CreateOptionsControls(panel)
local addonID = panel:GetName()
if(optionsState[addonID] == OPTIONS_CREATED) then
Expand Down Expand Up @@ -1024,9 +1068,9 @@ end

--METHOD: REGISTER ADDON PANEL
--registers your addon with LibAddonMenu and creates a panel
--Usage:
-- addonID = "string"; unique ID which will be the global name of your panel
-- panelData = table; data object for your panel - see controls\panel.lua
---@param addonID string unique ID which will be the global name of your panel
---@param panelData LAM2_PanelData data object for your panel - see controls\panel.lua
---@return LAM2_Panel
function lam:RegisterAddonPanel(addonID, panelData)
CheckSafetyAndInitialize(addonID)
local container = lam:GetAddonPanelContainer()
Expand Down Expand Up @@ -1067,11 +1111,10 @@ end
--registers the options you want shown for your addon
--these are stored in a table where each key-value pair is the order
--of the options in the panel and the data for that control, respectively
--see exampleoptions.lua for an example
--see controls\<widget>.lua for each widget type
--Usage:
-- addonID = "string"; the same string passed to :RegisterAddonPanel
-- optionsTable = table; the table containing all of the options controls and their data
---@see exampleoptions.lua for an example
---@see controls/<widget>.lua for each widget type
---@param addonID string the same string passed to :RegisterAddonPanel
---@param optionsTable LAM2_ControlData[] a list of data to create options controls from
function lam:RegisterOptionControls(addonID, optionsTable) --optionsTable = {sliderData, buttonData, etc}
addonToOptionsMap[addonID] = optionsTable
end
Expand All @@ -1096,7 +1139,7 @@ local function CreateAddonSettingsMenuEntry()
sm:AddFragment(lam:GetAddonSettingsFragment())
KEYBOARD_OPTIONS:ChangePanels(lam.panelId)

local title = LAMAddonSettingsWindow:GetNamedChild("Title")
local title = LAMAddonSettingsWindow:GetNamedChild("Title") --[[@as LabelControl]]
title:SetText(panelData.name)

if not addonListSorted and #addonsForList > 0 then
Expand All @@ -1122,7 +1165,7 @@ end
--INTERNAL FUNCTION
--creates the left-hand menu in LAM's window
local function CreateAddonList(name, parent)
local addonList = wm:CreateControlFromVirtual(name, parent, "ZO_ScrollList")
local addonList = wm:CreateControlFromVirtual(name, parent, "ZO_ScrollList") --[[@as ZO_ScrollList]]

local function addonListRow_OnMouseDown(control, button)
if button == 1 then
Expand Down Expand Up @@ -1166,7 +1209,7 @@ local function CreateAddonList(name, parent)
local addonListRow_CreateRaw = addonDataType.pool.m_Factory

local function addonListRow_Create(pool)
local control = addonListRow_CreateRaw(pool)
local control = addonListRow_CreateRaw(pool) --[[@as LabelControl]]
control:SetHandler("OnMouseDown", addonListRow_OnMouseDown)
--control:SetHandler("OnMouseEnter", addonListRow_OnMouseEnter)
--control:SetHandler("OnMouseExit", addonListRow_OnMouseExit)
Expand All @@ -1188,19 +1231,19 @@ end
local function CreateSearchFilterBox(name, parent)
local boxControl = wm:CreateControl(name, parent, CT_CONTROL)

local srchButton = wm:CreateControl("$(parent)Button", boxControl, CT_BUTTON)
local srchButton = wm:CreateControl("$(parent)Button", boxControl, CT_BUTTON) --[[@as ButtonControl]]
srchButton:SetDimensions(32, 32)
srchButton:SetAnchor(LEFT, nil, LEFT, 2, 0)
srchButton:SetNormalTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_up.dds")
srchButton:SetPressedTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_down.dds")
srchButton:SetMouseOverTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_over.dds")

local srchEdit = wm:CreateControlFromVirtual("$(parent)Edit", boxControl, "ZO_DefaultEdit")
local srchEdit = wm:CreateControlFromVirtual("$(parent)Edit", boxControl, "ZO_DefaultEdit") --[[@as EditControl]]
srchEdit:SetAnchor(LEFT, srchButton, RIGHT, 4, 1)
srchEdit:SetAnchor(RIGHT, nil, RIGHT, -4, 1)
srchEdit:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())

local srchBg = wm:CreateControl("$(parent)Bg", boxControl, CT_BACKDROP)
local srchBg = wm:CreateControl("$(parent)Bg", boxControl, CT_BACKDROP) --[[@as BackdropControl]]
srchBg:SetAnchorFill()
srchBg:SetAlpha(0)
srchBg:SetCenterColor(0, 0, 0, 0.5)
Expand Down Expand Up @@ -1291,21 +1334,23 @@ end
--creates LAM's Addon Settings top-level window
local function CreateAddonSettingsWindow()
local tlw = wm:CreateTopLevelWindow("LAMAddonSettingsWindow")
---@type Window
LAMAddonSettingsWindow = LAMAddonSettingsWindow
tlw:SetHidden(true)
tlw:SetDimensions(1010, 914) -- same height as ZO_OptionsWindow

ZO_ReanchorControlForLeftSidePanel(tlw)

-- create black background for the window (mimic ZO_RightFootPrintBackground)

local bgLeft = wm:CreateControl("$(parent)BackgroundLeft", tlw, CT_TEXTURE)
local bgLeft = wm:CreateControl("$(parent)BackgroundLeft", tlw, CT_TEXTURE) --[[@as TextureControl]]
bgLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_left.dds")
bgLeft:SetDimensions(1024, 1024)
bgLeft:SetAnchor(TOPLEFT, nil, TOPLEFT)
bgLeft:SetDrawLayer(DL_BACKGROUND)
bgLeft:SetExcludeFromResizeToFitExtents(true)

local bgRight = wm:CreateControl("$(parent)BackgroundRight", tlw, CT_TEXTURE)
local bgRight = wm:CreateControl("$(parent)BackgroundRight", tlw, CT_TEXTURE) --[[@as TextureControl]]
bgRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_right.dds")
bgRight:SetDimensions(64, 1024)
bgRight:SetAnchor(TOPLEFT, bgLeft, TOPRIGHT)
Expand All @@ -1314,14 +1359,14 @@ local function CreateAddonSettingsWindow()

-- create gray background for addon list (mimic ZO_TreeUnderlay)

local underlayLeft = wm:CreateControl("$(parent)UnderlayLeft", tlw, CT_TEXTURE)
local underlayLeft = wm:CreateControl("$(parent)UnderlayLeft", tlw, CT_TEXTURE) --[[@as TextureControl]]
underlayLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_left.dds")
underlayLeft:SetDimensions(256, 1024)
underlayLeft:SetAnchor(TOPLEFT, bgLeft, TOPLEFT)
underlayLeft:SetDrawLayer(DL_BACKGROUND)
underlayLeft:SetExcludeFromResizeToFitExtents(true)

local underlayRight = wm:CreateControl("$(parent)UnderlayRight", tlw, CT_TEXTURE)
local underlayRight = wm:CreateControl("$(parent)UnderlayRight", tlw, CT_TEXTURE) --[[@as TextureControl]]
underlayRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_right.dds")
underlayRight:SetDimensions(128, 1024)
underlayRight:SetAnchor(TOPLEFT, underlayLeft, TOPRIGHT)
Expand All @@ -1330,7 +1375,7 @@ local function CreateAddonSettingsWindow()

-- create title bar (mimic ZO_OptionsWindow)

local title = wm:CreateControl("$(parent)Title", tlw, CT_LABEL)
local title = wm:CreateControl("$(parent)Title", tlw, CT_LABEL) --[[@as LabelControl]]
title:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 70)
title:SetFont("ZoFontWinH1")
title:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE)
Expand Down
31 changes: 15 additions & 16 deletions LibAddonMenu-2.0/controls/button.lua
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
--[[buttonData = {
type = "button",
name = "My Button", -- string id or function returning a string
func = function() end,
tooltip = "Button's tooltip text.", -- string id or function returning a string (optional)
width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
icon = "icon\\path.dds", -- (optional)
isDangerous = false, -- boolean, if set to true, the button text will be red and a confirmation dialog with the button label and warning text will show on click before the callback is executed (optional)
warning = "Will need to reload the UI.", -- (optional)
helpUrl = "https://www.esoui.com/portal.php?id=218&a=faq", -- a string URL or a function that returns the string URL (optional)
reference = "MyAddonButton", -- unique global reference to control (optional)
resetFunc = function(buttonControl) d("defaults reset") end, -- custom function to run after the control is reset to defaults (optional)
} ]]
---@class LAM2_ButtonData: LAM2_BaseControlData
---@field type "button"
---@field func fun() will be called when the button is pressed
---@field tooltip nil|Stringy ex. "Button's tooltip text."
---@field disabled nil|boolean|fun(): boolean ex. function() return db.someBooleanSetting end
---@field icon nil|string ex. "icon\\path.dds"
---@field isDangerous nil|boolean if set to true, the button text will be red and a confirmation dialog with the button label and warning text will show on click before the callback is executed
---@field warning nil|Stringy ex. "Will need to reload the UI."
---@field resetFunc nil|fun(buttonControl: LAM2_Button) custom function to run after the control is reset to defaults ex. function(buttonControl) d("defaults reset") end

local widgetVersion = 12
local LAM = LibAddonMenu2
Expand All @@ -30,7 +25,10 @@ end
--controlName is optional
local MIN_HEIGHT = 28 -- default_button height
local HALF_WIDTH_LINE_SPACING = 2

---@param buttonData LAM2_ButtonData
function LAMCreateControl.button(parent, buttonData, controlName)
---@class LAM2_Button: LAM2_BaseControl
local control = LAM.util.CreateBaseControl(parent, buttonData, controlName)
control:SetMouseEnabled(true)

Expand All @@ -42,17 +40,18 @@ function LAMCreateControl.button(parent, buttonData, controlName)
end

if buttonData.icon then
control.button = wm:CreateControl(nil, control, CT_BUTTON)
control.button = wm:CreateControl(nil, control, CT_BUTTON) --[[@as LAM2_ButtonControl]]
control.button:SetDimensions(26, 26)
control.button:SetNormalTexture(buttonData.icon)
control.button:SetPressedOffset(2, 2)
else
--control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton")
control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton")
control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton") --[[@as LAM2_ButtonControl]]
control.button:SetWidth(width / 3)
control.button:SetText(LAM.util.GetStringFromValue(buttonData.name))
if buttonData.isDangerous then control.button:SetNormalFontColor(ZO_ERROR_COLOR:UnpackRGBA()) end
end
---@class LAM2_ButtonControl: ButtonControl
local button = control.button
button:SetAnchor(control.isHalfWidth and CENTER or RIGHT)
button:SetClickSound("Click")
Expand Down
Loading