-- LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah) -- -- All Rights Reserved -- -- Permission is granted to use Seerah's LibAddonMenu-2.0 -- -- in your project. Any modifications to LibAddonMenu-2.0 -- -- may not be redistributed. -- -------------------------------------------------------------- --Register LAM with LibStub local MAJOR, MINOR = "LibAddonMenu-2.0", 7 local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not lam then return end --the same or newer version of this lib is already loaded into memory --UPVALUES-- local wm = WINDOW_MANAGER local cm = CALLBACK_MANAGER local tinsert = table.insert local optionsWindow = ZO_OptionsWindowSettingsScrollChild local _ local addonsForList = {} local addonToOptionsMap = {} local optionsCreated = {} local widgets = {} --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 function lam:RegisterWidget(widgetType, widgetVersion) if widgets[widgetType] and widgets[widgetType] >= widgetVersion then return false else widgets[widgetType] = widgetVersion return true end end --METHOD: OPEN TO ADDON PANEL-- --opens to a specific addon's option panel --Usage: -- panel = userdata; the panel returned by the :RegisterOptionsPanel method --local settings = {en = "Settings", de = "Einstellungen", fr = "Réglages"} --local locSettings = settings[GetCVar("Language.2")] local locSettings = GetString(SI_GAME_MENU_SETTINGS) function lam:OpenToPanel(panel) SCENE_MANAGER:Show("gameMenuInGame") zo_callLater(function() ZO_GameMenu_InGame.gameMenu.headerControls[locSettings]:SetOpen(true) SCENE_MANAGER:AddFragment(OPTIONS_WINDOW_FRAGMENT) ZO_OptionsWindow_ChangePanels(lam.panelID) panel:SetHidden(false) end, 200) end --INTERNAL FUNCTION --creates controls when options panel is first shown --controls anchoring of these controls in the panel local function CreateOptionsControls(panel) local addonID = panel:GetName() local optionsTable = addonToOptionsMap[addonID] if optionsTable then local lastAddedControl, lacAtHalfRow for _, widgetData in ipairs(optionsTable) do local widgetType = widgetData.type if widgetType == "submenu" then local submenu = LAMCreateControl[widgetType](panel, widgetData) if lastAddedControl then submenu:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15) else submenu:SetAnchor(TOPLEFT) end lastAddedControl = submenu lacAtHalfRow = false local lastAddedControlSub, lacAtHalfRowSub for _, subWidgetData in ipairs(widgetData.controls) do local subWidgetType = subWidgetData.type local subWidget = LAMCreateControl[subWidgetType](submenu, subWidgetData) local isHalf = subWidgetData.width == "half" if lastAddedControlSub then if lacAtHalfRowSub and isHalf then subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, TOPRIGHT, 5, 0) lacAtHalfRowSub = false else subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, BOTTOMLEFT, 0, 15) lacAtHalfRowSub = isHalf and true or false lastAddedControlSub = subWidget end else subWidget:SetAnchor(TOPLEFT) lacAtHalfRowSub = isHalf and true or false lastAddedControlSub = subWidget end end else local widget = LAMCreateControl[widgetType](panel, widgetData) local isHalf = widgetData.width == "half" if lastAddedControl then if lacAtHalfRow and isHalf then widget:SetAnchor(TOPLEFT, lastAddedControl, TOPRIGHT, 10, 0) lacAtHalfRow = false else widget:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15) lacAtHalfRow = isHalf and true or false lastAddedControl = widget end else widget:SetAnchor(TOPLEFT) lacAtHalfRow = isHalf and true or false lastAddedControl = widget end end end end optionsCreated[addonID] = true cm:FireCallbacks("LAM-PanelControlsCreated", panel) end --INTERNAL FUNCTION --handles switching between panels local function ToggleAddonPanels(panel) --called in OnShow of newly shown panel local currentlySelected = LAMAddonPanelsMenu.currentlySelected if currentlySelected and currentlySelected ~= panel then currentlySelected:SetHidden(true) end LAMAddonPanelsMenu.currentlySelected = panel if not optionsCreated[panel:GetName()] then --if this is the first time opening this panel, create these options CreateOptionsControls(panel) end cm:FireCallbacks("LAM-RefreshPanel", panel) 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 function lam:RegisterAddonPanel(addonID, panelData) local panel = lamcc.panel(nil, panelData, addonID) --addonID==global name of panel panel:SetHidden(true) panel:SetAnchor(TOPLEFT, LAMAddonPanelsMenu, TOPRIGHT, 10, 0) panel:SetAnchor(BOTTOMLEFT, LAMAddonPanelsMenu, BOTTOMRIGHT, 10, 0) panel:SetWidth(549) panel:SetDrawLayer(DL_OVERLAY) tinsert(addonsForList, {panel = addonID, name = panelData.name}) panel:SetHandler("OnShow", ToggleAddonPanels) if panelData.slashCommand then SLASH_COMMANDS[panelData.slashCommand] = function() lam:OpenToPanel(panel) end end return panel --return for authors creating options manually end --METHOD: REGISTER OPTION CONTROLS --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 function lam:RegisterOptionControls(addonID, optionsTable) --optionsTable = {sliderData, buttonData, etc} addonToOptionsMap[addonID] = optionsTable end --INTERNAL FUNCTION --handles switching between LAM's Addon Settings panel and other panels in the Settings menu local oldDefaultButton = ZO_OptionsWindowResetToDefaultButton local oldCallback = oldDefaultButton.callback local dummyFunc = function() end local panelWindow = ZO_OptionsWindow local bgL = ZO_OptionsWindowBGLeft local bgR = ZO_OptionsWindowBGLeftBGRight local function HandlePanelSwitching(panel) if panel == lam.panelID then --our addon settings panel oldDefaultButton:SetCallback(dummyFunc) oldDefaultButton:SetHidden(true) oldDefaultButton:SetAlpha(0) --just because it still bugs out panelWindow:SetDimensions(999, 960) bgL:SetWidth(666) bgR:SetWidth(333) else local shown = LAMAddonPanelsMenu.currentlySelected if shown then shown:SetHidden(true) end oldDefaultButton:SetCallback(oldCallback) oldDefaultButton:SetHidden(false) oldDefaultButton:SetAlpha(1) panelWindow:SetDimensions(768, 914) bgL:SetWidth(512) bgR:SetWidth(256) end end --INTERNAL FUNCTION --creates LAM's Addon Settings panel local function CreateAddonSettingsPanel() if not LAMSettingsPanelCreated then local controlPanelID = "LAM_ADDON_SETTINGS_PANEL" local controlPanelNames = {en = "Addon Settings", fr = "Extensions", de = "Erweiterungen"} ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelNames[GetCVar("Language.2")]) lam.panelID = _G[controlPanelID] ZO_PreHook("ZO_OptionsWindow_ChangePanels", HandlePanelSwitching) LAMSettingsPanelCreated = true end end --INTERNAL FUNCTION --adds each registered addon to the menu in LAM's panel local function CreateAddonButtons(list, addons) for i = 1, #addons do local button = wm:CreateControlFromVirtual("LAMAddonMenuButton"..i, list, "ZO_DefaultTextButton") button.name = addons[i].name button.panel = _G[addons[i].panel] button:SetText(button.name) button:SetHorizontalAlignment(TEXT_ALIGN_LEFT) button:SetWidth(190) if i == 1 then button:SetAnchor(TOPLEFT, list, TOPLEFT, 5, 5) else button:SetAnchor(TOPLEFT, _G["LAMAddonMenuButton"..i-1], BOTTOMLEFT) end button:SetHandler("OnClicked", function(self) self.panel:SetHidden(false) end) end end --INTERNAL FUNCTION --creates the left-hand menu in LAM's panel local function CreateAddonList() local list --check if an earlier loaded copy of LAM created it already list = LAMAddonPanelsMenu or wm:CreateControlFromVirtual("LAMAddonPanelsMenu", optionsWindow, "ZO_ScrollContainer") list:ClearAnchors() list:SetAnchor(TOPLEFT) list:SetHeight(675) list:SetWidth(200) list.bg = list.bg or wm:CreateControl(nil, list, CT_BACKDROP) local bg = list.bg bg:SetAnchorFill() --offsets of 8? bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16) bg:SetCenterColor(0, 0, 0, 0) local generatedButtons list:SetHandler("OnShow", function(self) if not generatedButtons and #addonsForList > 0 then --we're about to show our list for the first time - let's sort the buttons before creating them table.sort(addonsForList, function(a, b) return a.name < b.name end) CreateAddonButtons(list, addonsForList) self.currentlySelected = LAMAddonMenuButton1 and LAMAddonMenuButton1.panel --since our addon panels don't have a parent, let's make sure they hide when we're done with them ZO_PreHookHandler(ZO_OptionsWindow, "OnHide", function() self.currentlySelected:SetHidden(true) end) generatedButtons = true end if self.currentlySelected then self.currentlySelected:SetHidden(false) end end) list.controlType = OPTIONS_CUSTOM list.panel = lam.panelID ZO_OptionsWindow_InitializeControl(list) return list end --INITIALIZING CreateAddonSettingsPanel() CreateAddonList()