100029 #5

Merged
fbrinker merged 6 commits from 100029 into master 2019-10-26 21:52:41 +00:00
17 changed files with 418 additions and 138 deletions
Showing only changes of commit 02cbf2cd2b - Show all commits

View File

@ -1,9 +1,11 @@
## APIVersion: 100022 100023 ## APIVersion: 100029 100030
## Title: LibAddonMenu-2.0 ## Title: LibAddonMenu-2.0
## Version: 2.0 r26 ## Version: 2.0 r30
## AddOnVersion: 26 ## AddOnVersion: 30
## IsLibrary: true
## OptionalDependsOn: LibStub LibDebugLogger
## Author: Seerah, sirinsidiator, et al. ## Author: Seerah, sirinsidiator, et al.
## Contributors: votan, merlight, Garkin, Randactyl, KuroiLight, silvereyes333, Baertram, kyoma ## Contributors: votan, merlight, Garkin, Randactyl, KuroiLight, silvereyes333, Baertram, kyoma, klingo, phuein
## Description: A library to aid in the creation of option panels. ## Description: A library to aid in the creation of option panels.
## ##
## This Add-on is not created by, affiliated with or sponsored by ZeniMax Media Inc. or its affiliates. ## This Add-on is not created by, affiliated with or sponsored by ZeniMax Media Inc. or its affiliates.

View File

@ -4,9 +4,10 @@
--Register LAM with LibStub --Register LAM with LibStub
local MAJOR, MINOR = "LibAddonMenu-2.0", 26 local MAJOR, MINOR = "LibAddonMenu-2.0", 30
local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR) 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 if not lam then return end --the same or newer version of this lib is already loaded into memory
LibAddonMenu2 = lam
local messages = {} local messages = {}
local MESSAGE_PREFIX = "[LAM2] " local MESSAGE_PREFIX = "[LAM2] "
@ -25,6 +26,11 @@ local function FlushMessages()
messages = {} messages = {}
end end
local logger
if LibDebugLogger then
logger = LibDebugLogger(MAJOR)
end
if LAMSettingsPanelCreated and not LAMCompatibilityWarning then 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") 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 LAMCompatibilityWarning = true
@ -72,6 +78,10 @@ local function GetStringFromValue(value)
return value return value
end end
local function GetColorForState(disabled)
return disabled and ZO_DEFAULT_DISABLED_COLOR or ZO_DEFAULT_ENABLED_COLOR
end
local function CreateBaseControl(parent, controlData, controlName) local function CreateBaseControl(parent, controlData, controlName)
local control = wm:CreateControl(controlName or controlData.reference, parent.scroll or parent, CT_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.panel = parent.panel or parent -- if this is in a submenu, panel is the submenu's parent
@ -144,12 +154,14 @@ local function RefreshReloadUIButton()
end end
end end
if lam.applyButton then
lam.applyButton:SetHidden(not lam.requiresReload) lam.applyButton:SetHidden(not lam.requiresReload)
end
end end
local function RequestRefreshIfNeeded(control) local function RequestRefreshIfNeeded(control)
-- if our parent window wants to refresh controls, then fire the callback -- if our parent window wants to refresh controls, then fire the callback
local panel = GetTopPanel(control.panel) local panel = GetTopPanel(control)
local panelData = panel.data local panelData = panel.data
if panelData.registerForRefresh then if panelData.registerForRefresh then
cm:FireCallbacks("LAM-RefreshPanel", control) cm:FireCallbacks("LAM-RefreshPanel", control)
@ -313,9 +325,9 @@ local function UpdateWarning(control)
if control.data.requiresReload then if control.data.requiresReload then
if not warning then if not warning then
warning = string.format("|cff0000%s", util.L["RELOAD_UI_WARNING"]) warning = string.format("%s", util.L["RELOAD_UI_WARNING"])
else else
warning = string.format("%s\n\n|cff0000%s", warning, util.L["RELOAD_UI_WARNING"]) warning = string.format("%s\n\n%s", warning, util.L["RELOAD_UI_WARNING"])
end end
end end
@ -333,10 +345,13 @@ local localization = {
AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Author: <<X:1>>" AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Author: <<X:1>>"
VERSION = "Version: <<X:1>>", VERSION = "Version: <<X:1>>",
WEBSITE = "Visit Website", WEBSITE = "Visit Website",
FEEDBACK = "Feedback",
TRANSLATION = "Translation",
DONATION = "Donate",
PANEL_INFO_FONT = "$(CHAT_FONT)|14|soft-shadow-thin", PANEL_INFO_FONT = "$(CHAT_FONT)|14|soft-shadow-thin",
RELOAD_UI_WARNING = "Changes to this setting require an UI reload in order to take effect.", RELOAD_UI_WARNING = "Changes to this setting require a UI reload in order to take effect.",
RELOAD_DIALOG_TITLE = "UI Reload required", RELOAD_DIALOG_TITLE = "UI Reload Required",
RELOAD_DIALOG_TEXT = "Some changes require an UI reload in order to take effect. Do you want to reload now or discard the changes?", RELOAD_DIALOG_TEXT = "Some changes require a UI reload in order to take effect. Do you want to reload now or discard the changes?",
RELOAD_DIALOG_RELOAD_BUTTON = "Reload", RELOAD_DIALOG_RELOAD_BUTTON = "Reload",
RELOAD_DIALOG_DISCARD_BUTTON = "Discard", RELOAD_DIALOG_DISCARD_BUTTON = "Discard",
}, },
@ -344,6 +359,9 @@ local localization = {
PANEL_NAME = "Addon", PANEL_NAME = "Addon",
VERSION = "Versione: <<X:1>>", VERSION = "Versione: <<X:1>>",
WEBSITE = "Visita il Sitoweb", WEBSITE = "Visita il Sitoweb",
FEEDBACK = "Feedback",
TRANSLATION = "Traduzione",
DONATION = "Donare",
RELOAD_UI_WARNING = "Cambiare questa impostazione richiede un Ricarica UI al fine che faccia effetto.", RELOAD_UI_WARNING = "Cambiare questa impostazione richiede un Ricarica UI al fine che faccia effetto.",
RELOAD_DIALOG_TITLE = "Ricarica UI richiesto", RELOAD_DIALOG_TITLE = "Ricarica UI richiesto",
RELOAD_DIALOG_TEXT = "Alcune modifiche richiedono un Ricarica UI al fine che facciano effetto. Sei sicuro di voler ricaricare ora o di voler annullare le modifiche?", RELOAD_DIALOG_TEXT = "Alcune modifiche richiedono un Ricarica UI al fine che facciano effetto. Sei sicuro di voler ricaricare ora o di voler annullare le modifiche?",
@ -353,6 +371,9 @@ local localization = {
fr = { -- provided by Ayantir fr = { -- provided by Ayantir
PANEL_NAME = "Extensions", PANEL_NAME = "Extensions",
WEBSITE = "Visiter le site Web", WEBSITE = "Visiter le site Web",
FEEDBACK = "Réaction",
TRANSLATION = "Traduction",
DONATION = "Donner",
RELOAD_UI_WARNING = "La modification de ce paramètre requiert un rechargement de l'UI pour qu'il soit pris en compte.", RELOAD_UI_WARNING = "La modification de ce paramètre requiert un rechargement de l'UI pour qu'il soit pris en compte.",
RELOAD_DIALOG_TITLE = "Reload UI requis", RELOAD_DIALOG_TITLE = "Reload UI requis",
RELOAD_DIALOG_TEXT = "Certaines modifications requièrent un rechargement de l'UI pour qu'ils soient pris en compte. Souhaitez-vous recharger l'interface maintenant ou annuler les modifications ?", RELOAD_DIALOG_TEXT = "Certaines modifications requièrent un rechargement de l'UI pour qu'ils soient pris en compte. Souhaitez-vous recharger l'interface maintenant ou annuler les modifications ?",
@ -362,6 +383,9 @@ local localization = {
de = { -- provided by sirinsidiator de = { -- provided by sirinsidiator
PANEL_NAME = "Erweiterungen", PANEL_NAME = "Erweiterungen",
WEBSITE = "Webseite besuchen", WEBSITE = "Webseite besuchen",
FEEDBACK = "Feedback",
TRANSLATION = "Übersetzung",
DONATION = "Spende",
RELOAD_UI_WARNING = "Änderungen an dieser Option werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird.", RELOAD_UI_WARNING = "Änderungen an dieser Option werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird.",
RELOAD_DIALOG_TITLE = "Neuladen benötigt", RELOAD_DIALOG_TITLE = "Neuladen benötigt",
RELOAD_DIALOG_TEXT = "Einige Änderungen werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird. Wollt Ihr sie jetzt neu laden oder die Änderungen verwerfen?", RELOAD_DIALOG_TEXT = "Einige Änderungen werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird. Wollt Ihr sie jetzt neu laden oder die Änderungen verwerfen?",
@ -372,6 +396,9 @@ local localization = {
PANEL_NAME = "Дополнения", PANEL_NAME = "Дополнения",
VERSION = "Версия: <<X:1>>", VERSION = "Версия: <<X:1>>",
WEBSITE = "Посетить сайт", WEBSITE = "Посетить сайт",
FEEDBACK = "отзыв",
TRANSLATION = "Перевод",
DONATION = "жертвовать",
PANEL_INFO_FONT = "RuESO/fonts/Univers57.otf|14|soft-shadow-thin", PANEL_INFO_FONT = "RuESO/fonts/Univers57.otf|14|soft-shadow-thin",
RELOAD_UI_WARNING = "Для применения этой настройки необходима перезагрузка интерфейса.", RELOAD_UI_WARNING = "Для применения этой настройки необходима перезагрузка интерфейса.",
RELOAD_DIALOG_TITLE = "Необходима перезагрузка интерфейса", RELOAD_DIALOG_TITLE = "Необходима перезагрузка интерфейса",
@ -383,6 +410,9 @@ local localization = {
PANEL_NAME = "Configuración", PANEL_NAME = "Configuración",
VERSION = "Versión: <<X:1>>", VERSION = "Versión: <<X:1>>",
WEBSITE = "Visita la página web", WEBSITE = "Visita la página web",
FEEDBACK = "Reaccion",
TRANSLATION = "Traducción",
DONATION = "Donar",
RELOAD_UI_WARNING = "Cambiar este ajuste recargará la interfaz del usuario.", RELOAD_UI_WARNING = "Cambiar este ajuste recargará la interfaz del usuario.",
RELOAD_DIALOG_TITLE = "Requiere recargar la interfaz", RELOAD_DIALOG_TITLE = "Requiere recargar la interfaz",
RELOAD_DIALOG_TEXT = "Algunos cambios requieren recargar la interfaz para poder aplicarse. Quieres aplicar los cambios y recargar la interfaz?", RELOAD_DIALOG_TEXT = "Algunos cambios requieren recargar la interfaz para poder aplicarse. Quieres aplicar los cambios y recargar la interfaz?",
@ -392,6 +422,9 @@ local localization = {
jp = { -- provided by k0ta0uchi jp = { -- provided by k0ta0uchi
PANEL_NAME = "アドオン設定", PANEL_NAME = "アドオン設定",
WEBSITE = "ウェブサイトを見る", WEBSITE = "ウェブサイトを見る",
FEEDBACK = "フィードバック",
TRANSLATION = "訳書",
DONATION = "寄贈する",
}, },
zh = { -- provided by bssthu zh = { -- provided by bssthu
PANEL_NAME = "插件", PANEL_NAME = "插件",
@ -409,34 +442,49 @@ local localization = {
RELOAD_DIALOG_RELOAD_BUTTON = "Przeładuj", RELOAD_DIALOG_RELOAD_BUTTON = "Przeładuj",
RELOAD_DIALOG_DISCARD_BUTTON = "Porzuć", RELOAD_DIALOG_DISCARD_BUTTON = "Porzuć",
}, },
kr = { -- provided by p.walker br = { -- provided by mlsevero & FelipeS11
PANEL_NAME = "蝠盜蠨",
VERSION = "纄訄: <<X:1>>",
WEBSITE = "裹芬襴钸 縩紸",
PANEL_INFO_FONT = "EsoKR/fonts/Univers57.otf|14|soft-shadow-thin",
RELOAD_UI_WARNING = "襴 茤訕襄 绀溽靘籴 風滼筼 訁袩靘瀰褄靴 UI 苈穜滠遨襴 靄袔革瓈瓤.",
RELOAD_DIALOG_TITLE = "UI 苈穜滠遨 靄袔",
RELOAD_DIALOG_TEXT = "绀溽瘜 茤訕 謑 UI 苈穜滠遨襄 靄袔穜靘璔 芬靭襴 覈蒵瓈瓤. 诀瀈 苈穜滠遨靘蓜溠蒵瓈灌? 蝄瓈籴 绀溽襄 迨莌靘蓜溠蒵瓈灌?",
RELOAD_DIALOG_RELOAD_BUTTON = "苈穜滠遨",
RELOAD_DIALOG_DISCARD_BUTTON = "绀溽迨莌",
},
br = { -- provided by mlsevero
PANEL_NAME = "Addons", PANEL_NAME = "Addons",
AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Autor: <<X:1>>" AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Autor: <<X:1>>"
VERSION = "Versão: <<X:1>>", VERSION = "Versão: <<X:1>>",
WEBSITE = "Visite o Website", WEBSITE = "Visite o Website",
RELOAD_UI_WARNING = "Mudanças nessa configuração requer a releitura da UI para ter efeito.", FEEDBACK = "Feedback",
RELOAD_DIALOG_TITLE = "Releitura da UI requerida", TRANSLATION = "Tradução",
RELOAD_DIALOG_TEXT = "Algumas mudanças requerem a releitura da UI para ter efeito. Você deseja reler agora ou descartar as mudanças?", DONATION = "Doação",
RELOAD_DIALOG_RELOAD_BUTTON = "Relê", RELOAD_UI_WARNING = "Mudanças nessa configuração requerem o recarregamento da UI para ter efeito.",
RELOAD_DIALOG_DISCARD_BUTTON = "Descarta", RELOAD_DIALOG_TITLE = "Recarregamento da UI requerida",
RELOAD_DIALOG_TEXT = "Algumas mudanças requerem o recarregamento da UI para ter efeito. Você deseja recarregar agora ou descartar as mudanças?",
RELOAD_DIALOG_RELOAD_BUTTON = "Recarregar",
RELOAD_DIALOG_DISCARD_BUTTON = "Descartar",
}, },
} }
util.L = ZO_ShallowTableCopy(localization[GetCVar("Language.2")] or {}, localization["en"]) do
local EsoKR = EsoKR
if EsoKR and EsoKR:isKorean() then
util.L = ZO_ShallowTableCopy({ -- provided by whya5448
PANEL_NAME = EsoKR:E("애드온"),
AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Author: <<X:1>>"
VERSION = EsoKR:E("버전: <<X:1>>"),
WEBSITE = EsoKR:E("웹사이트 방문"),
FEEDBACK = EsoKR:E("피드백"),
TRANSLATION = EsoKR:E("번역"),
DONATION = EsoKR:E("기부"),
PANEL_INFO_FONT = "EsoKR/fonts/Univers57.otf|14|soft-shadow-thin",
RELOAD_UI_WARNING = EsoKR:E("이 설정을 변경하면 효과를 적용하기위해 UI 새로고침이 필요합니다."),
RELOAD_DIALOG_TITLE = EsoKR:E("UI 새로고침 필요"),
RELOAD_DIALOG_TEXT = EsoKR:E("변경된 설정 중 UI 새로고침을 필요로하는 사항이 있습니다. 지금 새로고침하시겠습니까? 아니면 변경을 취소하시겠습니까?"),
RELOAD_DIALOG_RELOAD_BUTTON = EsoKR:E("새로고침"),
RELOAD_DIALOG_DISCARD_BUTTON = EsoKR:E("변경취소"),
}, localization["en"])
else
util.L = ZO_ShallowTableCopy(localization[GetCVar("Language.2")] or {}, localization["en"])
end
end
util.GetTooltipText = GetStringFromValue -- deprecated, use util.GetStringFromValue instead util.GetTooltipText = GetStringFromValue -- deprecated, use util.GetStringFromValue instead
util.GetStringFromValue = GetStringFromValue util.GetStringFromValue = GetStringFromValue
util.GetDefaultValue = GetDefaultValue util.GetDefaultValue = GetDefaultValue
util.GetColorForState = GetColorForState
util.CreateBaseControl = CreateBaseControl util.CreateBaseControl = CreateBaseControl
util.CreateLabelAndContainerControl = CreateLabelAndContainerControl util.CreateLabelAndContainerControl = CreateLabelAndContainerControl
util.RequestRefreshIfNeeded = RequestRefreshIfNeeded util.RequestRefreshIfNeeded = RequestRefreshIfNeeded
@ -776,6 +824,9 @@ local function CreateOptionsControls(panel)
err, anchorOffset, lastAddedControl, wasHalf = CreateAndAnchorWidget(parent, widgetData, offsetX, anchorOffset, lastAddedControl, wasHalf) err, anchorOffset, lastAddedControl, wasHalf = CreateAndAnchorWidget(parent, widgetData, offsetX, anchorOffset, lastAddedControl, wasHalf)
if err then if err then
PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, GetStringFromValue(widgetData.name or "unnamed"), addonID)) PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, GetStringFromValue(widgetData.name or "unnamed"), addonID))
if logger then
logger:Error(err)
end
end end
if isSubmenu then if isSubmenu then
@ -833,6 +884,22 @@ local function ToggleAddonPanels(panel) --called in OnShow of newly shown panel
end end
local CheckSafetyAndInitialize local CheckSafetyAndInitialize
local function ShowSetHandlerWarning(panel, handler)
local hint
if(handler == "OnShow" or handler == "OnEffectivelyShown") then
hint = "'LAM-PanelControlsCreated' or 'LAM-PanelOpened'"
elseif(handler == "OnHide" or handler == "OnEffectivelyHidden") then
hint = "'LAM-PanelClosed'"
end
if hint then
local message = ("Setting a handler on a panel is not recommended. Use the global callback %s instead. (%s on %s)"):format(hint, handler, panel.data.name)
PrintLater(message)
if logger then
logger:Warn(message)
end
end
end
--METHOD: REGISTER ADDON PANEL --METHOD: REGISTER ADDON PANEL
--registers your addon with LibAddonMenu and creates a panel --registers your addon with LibAddonMenu and creates a panel
@ -845,7 +912,8 @@ function lam:RegisterAddonPanel(addonID, panelData)
local panel = lamcc.panel(container, panelData, addonID) --addonID==global name of panel local panel = lamcc.panel(container, panelData, addonID) --addonID==global name of panel
panel:SetHidden(true) panel:SetHidden(true)
panel:SetAnchorFill(container) panel:SetAnchorFill(container)
panel:SetHandler("OnShow", ToggleAddonPanels) panel:SetHandler("OnEffectivelyShown", ToggleAddonPanels)
ZO_PreHook(panel, "SetHandler", ShowSetHandlerWarning)
local function stripMarkup(str) local function stripMarkup(str)
return str:gsub("|[Cc]%x%x%x%x%x%x", ""):gsub("|[Rr]", "") return str:gsub("|[Cc]%x%x%x%x%x%x", ""):gsub("|[Rr]", "")
@ -897,6 +965,7 @@ local function CreateAddonSettingsMenuEntry()
KEYBOARD_OPTIONS.currentPanelId = panelData.id + 1 KEYBOARD_OPTIONS.currentPanelId = panelData.id + 1
KEYBOARD_OPTIONS.panelNames[panelData.id] = panelData.name KEYBOARD_OPTIONS.panelNames[panelData.id] = panelData.name
KEYBOARD_OPTIONS.controlTable[panelData.id] = {}
lam.panelId = panelData.id lam.panelId = panelData.id

View File

@ -3,11 +3,11 @@
name = "My Button", -- string id or function returning a string name = "My Button", -- string id or function returning a string
func = function() end, func = function() end,
tooltip = "Button's tooltip text.", -- string id or function returning a string (optional) tooltip = "Button's tooltip text.", -- string id or function returning a string (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
icon = "icon\\path.dds", --(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) 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) warning = "Will need to reload the UI.", -- (optional)
reference = "MyAddonButton", -- unique global reference to control (optional) reference = "MyAddonButton", -- unique global reference to control (optional)
} ]] } ]]

View File

@ -5,7 +5,7 @@
setFunc = function(value) db.var = value doStuff() end, setFunc = function(value) db.var = value doStuff() end,
tooltip = "Checkbox's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Checkbox's tooltip text.", -- or string id or function returning a string (optional)
width = "full", -- or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
default = defaults.var, -- a boolean or function that returns a boolean (optional) default = defaults.var, -- a boolean or function that returns a boolean (optional)

View File

@ -1,19 +1,19 @@
--[[colorpickerData = { --[[colorpickerData = {
type = "colorpicker", type = "colorpicker",
name = "My Color Picker", -- or string id or function returning a string name = "My Color Picker", -- or string id or function returning a string
getFunc = function() return db.r, db.g, db.b, db.a end, --(alpha is optional) getFunc = function() return db.r, db.g, db.b, db.a end, -- (alpha is optional)
setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end, --(alpha is optional) setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end, -- (alpha is optional)
tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a}, --(optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a]) or a function that returns the color default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a}, -- (optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a]) or a function that returns the color
reference = "MyAddonColorpicker" -- unique global reference to control (optional) reference = "MyAddonColorpicker" -- unique global reference to control (optional)
} ]] } ]]
local widgetVersion = 13 local widgetVersion = 14
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
@ -79,7 +79,11 @@ function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
if upInside then if upInside then
local r, g, b, a = colorpickerData.getFunc() local r, g, b, a = colorpickerData.getFunc()
COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, LAM.util.GetStringFromValue(colorpickerData.name)) if IsInGamepadPreferredMode() then
COLOR_PICKER_GAMEPAD:Show(ColorPickerCallback, r, g, b, a)
else
COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a)
end
end end
end) end)

View File

@ -1,8 +1,8 @@
--[[customData = { --[[customData = {
type = "custom", type = "custom",
reference = "MyAddonCustomControl", --(optional) unique name for your control to use as reference reference = "MyAddonCustomControl", -- unique name for your control to use as reference (optional)
refreshFunc = function(customControl) end, --(optional) function to call when panel/controls refresh refreshFunc = function(customControl) end, -- function to call when panel/controls refresh (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
} ]] } ]]
local widgetVersion = 7 local widgetVersion = 7

View File

@ -2,17 +2,39 @@
type = "description", type = "description",
text = "My description text to display.", -- or string id or function returning a string text = "My description text to display.", -- or string id or function returning a string
title = "My Title", -- or string id or function returning a string (optional) title = "My Title", -- or string id or function returning a string (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
enableLinks = nil, -- or true for default tooltips, or function OnLinkClicked handler (optional)
-- see: https://wiki.esoui.com/UI_XML#OnLinkClicked
reference = "MyAddonDescription" -- unique global reference to control (optional) reference = "MyAddonDescription" -- unique global reference to control (optional)
} ]] } ]]
local widgetVersion = 8 local widgetVersion = 10
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("description", widgetVersion) then return end if not LAM:RegisterWidget("description", widgetVersion) then return end
local wm = WINDOW_MANAGER local wm = WINDOW_MANAGER
local GetDefaultValue = LAM.util.GetDefaultValue
local GetColorForState = LAM.util.GetColorForState
local function OnLinkClicked(control, linkData, linkText, button)
ZO_LinkHandler_OnLinkClicked(linkText, button)
end
local function UpdateDisabled(control)
local disable = GetDefaultValue(control.data.disabled)
if disable ~= control.disabled then
local color = GetColorForState(disable)
control.desc:SetColor(color:UnpackRGBA())
if control.title then
control.title:SetColor(color:UnpackRGBA())
end
control.disabled = disable
end
end
local function UpdateValue(control) local function UpdateValue(control)
if control.title then if control.title then
control.title:SetText(LAM.util.GetStringFromValue(control.data.title)) control.title:SetText(LAM.util.GetStringFromValue(control.data.title))
@ -51,7 +73,21 @@ function LAMCreateControl.description(parent, descriptionData, controlName)
desc:SetAnchor(TOPLEFT) desc:SetAnchor(TOPLEFT)
end end
if descriptionData.enableLinks then
desc:SetMouseEnabled(true)
desc:SetLinkEnabled(true)
if type(descriptionData.enableLinks) == "function" then
desc:SetHandler("OnLinkClicked", descriptionData.enableLinks)
else
desc:SetHandler("OnLinkClicked", OnLinkClicked)
end
end
control.UpdateValue = UpdateValue control.UpdateValue = UpdateValue
if descriptionData.disabled ~= nil then
control.UpdateDisabled = UpdateDisabled
control:UpdateDisabled()
end
LAM.util.RegisterForRefreshIfNeeded(control) LAM.util.RegisterForRefreshIfNeeded(control)

View File

@ -1,8 +1,8 @@
--[[dividerData = { --[[dividerData = {
type = "divider", type = "divider",
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
height = 10, (optional) height = 10, -- (optional)
alpha = 0.25, (optional) alpha = 0.25, -- (optional)
reference = "MyAddonDivider" -- unique global reference to control (optional) reference = "MyAddonDivider" -- unique global reference to control (optional)
} ]] } ]]

View File

@ -7,10 +7,10 @@
setFunc = function(var) db.var = var doStuff() end, setFunc = function(var) db.var = var doStuff() end,
tooltip = "Dropdown's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Dropdown's tooltip text.", -- or string id or function returning a string (optional)
choicesTooltips = {"tooltip 1", "tooltip 2", "tooltip 3"}, -- or array of string ids or array of functions returning a string (optional) choicesTooltips = {"tooltip 1", "tooltip 2", "tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
sort = "name-up", --or "name-down", "numeric-up", "numeric-down", "value-up", "value-down", "numericvalue-up", "numericvalue-down" (optional) - if not provided, list will not be sorted sort = "name-up", -- or "name-down", "numeric-up", "numeric-down", "value-up", "value-down", "numericvalue-up", "numericvalue-down" (optional) - if not provided, list will not be sorted
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
scrollable = true, -- boolean or number, if set the dropdown will feature a scroll bar if there are a large amount of choices and limit the visible lines to the specified number or 10 if true is used (optional) scrollable = true, -- boolean or number, if set the dropdown will feature a scroll bar if there are a large amount of choices and limit the visible lines to the specified number or 10 if true is used (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
default = defaults.var, -- default value or function that returns the default value (optional) default = defaults.var, -- default value or function that returns the default value (optional)
@ -18,11 +18,12 @@
} ]] } ]]
local widgetVersion = 18 local widgetVersion = 20
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("dropdown", widgetVersion) then return end if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
local wm = WINDOW_MANAGER local wm = WINDOW_MANAGER
local cm = CALLBACK_MANAGER
local SORT_BY_VALUE = { ["value"] = {} } local SORT_BY_VALUE = { ["value"] = {} }
local SORT_BY_VALUE_NUMERIC = { ["value"] = { isNumeric = true } } local SORT_BY_VALUE_NUMERIC = { ["value"] = { isNumeric = true } }
local SORT_TYPES = { local SORT_TYPES = {
@ -155,11 +156,16 @@ local function GrabSortingInfo(sortInfo)
return t return t
end end
local ENTRY_ID = 1
local LAST_ENTRY_ID = 2
local OFFSET_X_INDEX = 4
local DEFAULT_VISIBLE_ROWS = 10 local DEFAULT_VISIBLE_ROWS = 10
local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = 25 -- same as in zo_combobox.lua local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = ZO_SCROLLABLE_ENTRY_TEMPLATE_HEIGHT
local CONTENT_PADDING = 24 local SCROLLBAR_PADDING = ZO_SCROLL_BAR_WIDTH
local SCROLLBAR_PADDING = 16 local PADDING_X = GetMenuPadding()
local PADDING = GetMenuPadding() / 2 -- half the amount looks closer to the regular dropdown local PADDING_Y = ZO_SCROLLABLE_COMBO_BOX_LIST_PADDING_Y
local LABEL_OFFSET_X = 2
local CONTENT_PADDING = PADDING_X * 4
local ROUNDING_MARGIN = 0.01 -- needed to avoid rare issue with too many anchors processed local ROUNDING_MARGIN = 0.01 -- needed to avoid rare issue with too many anchors processed
local ScrollableDropdownHelper = ZO_Object:Subclass() local ScrollableDropdownHelper = ZO_Object:Subclass()
@ -169,10 +175,10 @@ function ScrollableDropdownHelper:New(...)
return object return object
end end
function ScrollableDropdownHelper:Initialize(parent, control, visibleRows) function ScrollableDropdownHelper:Initialize(panel, control, visibleRows)
local combobox = control.combobox local combobox = control.combobox
local dropdown = control.dropdown local dropdown = control.dropdown
self.parent = parent self.panel = panel
self.control = control self.control = control
self.combobox = combobox self.combobox = combobox
self.dropdown = dropdown self.dropdown = dropdown
@ -183,14 +189,16 @@ function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT) dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT)
-- handle dropdown or settingsmenu opening/closing -- handle dropdown or settingsmenu opening/closing
local function onShow() self:OnShow() end local function onShow() return self:OnShow() end
local function onHide() self:OnHide() end local function onHide() self:OnHide() end
local function doHide() self:DoHide() end local function doHide(closedPanel)
if closedPanel == panel then self:DoHide() end
end
ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow) ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow)
ZO_PreHook(dropdown, "HideDropdownInternal", onHide) ZO_PreHook(dropdown, "HideDropdownInternal", onHide)
combobox:SetHandler("OnEffectivelyHidden", onHide) combobox:SetHandler("OnEffectivelyHidden", onHide)
parent:SetHandler("OnEffectivelyHidden", doHide) cm:RegisterCallback("LAM-PanelClosed", doHide)
-- dont fade entries near the edges -- dont fade entries near the edges
local scrollList = dropdown.m_scroll local scrollList = dropdown.m_scroll
@ -202,11 +210,13 @@ function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
-- adjust scroll content anchor to mimic menu padding -- adjust scroll content anchor to mimic menu padding
local scroll = dropdown.m_dropdown:GetNamedChild("Scroll") local scroll = dropdown.m_dropdown:GetNamedChild("Scroll")
local anchor1 = {scroll:GetAnchor(0)} local anchor1 = {select(2, scroll:GetAnchor(0))}
local anchor2 = {scroll:GetAnchor(1)} local anchor2 = {select(2, scroll:GetAnchor(1))}
anchor1[OFFSET_X_INDEX] = PADDING_X - LABEL_OFFSET_X
anchor2[OFFSET_X_INDEX] = -anchor1[OFFSET_X_INDEX]
scroll:ClearAnchors() scroll:ClearAnchors()
scroll:SetAnchor(anchor1[2], anchor1[3], anchor1[4], anchor1[5] + PADDING, anchor1[6] + PADDING) scroll:SetAnchor(unpack(anchor1))
scroll:SetAnchor(anchor2[2], anchor2[3], anchor2[4], anchor2[5] - PADDING, anchor2[6] - PADDING) scroll:SetAnchor(unpack(anchor2))
ZO_ScrollList_Commit(scrollList) ZO_ScrollList_Commit(scrollList)
-- hook mouse enter/exit -- hook mouse enter/exit
@ -214,20 +224,18 @@ function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
local function onMouseExit(control) self:OnMouseExit(control) end local function onMouseExit(control) self:OnMouseExit(control) end
-- adjust row setup to mimic the highlight padding -- adjust row setup to mimic the highlight padding
local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1) local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, ENTRY_ID)
local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 2) local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, LAST_ENTRY_ID)
local oSetup = dataType1.setupCallback -- both types have the same setup function local oSetup = dataType1.setupCallback -- both types have the same setup function
local function SetupEntry(control, data, list) local function SetupEntry(control, data, list)
oSetup(control, data, list) oSetup(control, data, list)
control.m_label:SetAnchor(LEFT, nil, nil, 2) control.m_label:SetAnchor(LEFT, nil, nil, LABEL_OFFSET_X)
control.m_label:SetAnchor(RIGHT, nil, nil, -LABEL_OFFSET_X)
-- no need to store old ones since we have full ownership of our dropdown controls -- no need to store old ones since we have full ownership of our dropdown controls
if not control.hookedMouseHandlers then --only do it once per control if not control.hookedMouseHandlers then --only do it once per control
control.hookedMouseHandlers = true control.hookedMouseHandlers = true
ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter) ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter)
ZO_PreHookHandler(control, "OnMouseExit", onMouseExit) ZO_PreHookHandler(control, "OnMouseExit", onMouseExit)
-- we could also just replace the handlers
--control:SetHandler("OnMouseEnter", onMouseEnter)
--control:SetHandler("OnMouseExit", onMouseExit)
end end
end end
dataType1.setupCallback = SetupEntry dataType1.setupCallback = SetupEntry
@ -235,24 +243,61 @@ function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
-- adjust dimensions based on entries -- adjust dimensions based on entries
local scrollContent = scroll:GetNamedChild("Contents") local scrollContent = scroll:GetNamedChild("Contents")
ZO_PreHook(dropdown, "AddMenuItems", function() dropdown.AddMenuItems = ScrollableDropdownHelper.AddMenuItems
local width = PADDING * 2 + zo_max(self:GetMaxWidth(), combobox:GetWidth())
dropdown.AdjustDimensions = function()
local numItems = #dropdown.m_sortedItems local numItems = #dropdown.m_sortedItems
local contentWidth = self:CalculateContentWidth() + CONTENT_PADDING
local anchorOffset = 0 local anchorOffset = 0
if(numItems > self.visibleRows) then if(numItems > self.visibleRows) then
width = width + CONTENT_PADDING + SCROLLBAR_PADDING
anchorOffset = -SCROLLBAR_PADDING
numItems = self.visibleRows numItems = self.visibleRows
contentWidth = contentWidth + SCROLLBAR_PADDING
anchorOffset = -SCROLLBAR_PADDING
end end
scrollContent:SetAnchor(BOTTOMRIGHT, nil, nil, anchorOffset)
local height = PADDING * 2 + numItems * (SCROLLABLE_ENTRY_TEMPLATE_HEIGHT + dropdown.m_spacing) - dropdown.m_spacing + ROUNDING_MARGIN local width = zo_max(contentWidth, dropdown.m_container:GetWidth())
local height = dropdown:GetEntryTemplateHeightWithSpacing() * numItems - dropdown.m_spacing + (PADDING_Y * 2) + ROUNDING_MARGIN
dropdown.m_dropdown:SetWidth(width) dropdown.m_dropdown:SetWidth(width)
dropdown.m_dropdown:SetHeight(height) dropdown.m_dropdown:SetHeight(height)
end) ZO_ScrollList_SetHeight(dropdown.m_scroll, height)
scrollContent:SetAnchor(BOTTOMRIGHT, nil, nil, anchorOffset)
end
end
local function CreateScrollableComboBoxEntry(self, item, index, isLast)
item.m_index = index
item.m_owner = self
local entryType = isLast and LAST_ENTRY_ID or ENTRY_ID
local entry = ZO_ScrollList_CreateDataEntry(entryType, item)
return entry
end
function ScrollableDropdownHelper.AddMenuItems(self) -- self refers to the ZO_ScrollableComboBox here
ZO_ScrollList_Clear(self.m_scroll)
local numItems = #self.m_sortedItems
local dataList = ZO_ScrollList_GetDataList(self.m_scroll)
for i = 1, numItems do
local item = self.m_sortedItems[i]
local entry = CreateScrollableComboBoxEntry(self, item, i, i == numItems)
table.insert(dataList, entry)
end
self:AdjustDimensions()
ZO_ScrollList_Commit(self.m_scroll)
end end
function ScrollableDropdownHelper:OnShow() function ScrollableDropdownHelper:OnShow()
local dropdown = self.dropdown local dropdown = self.dropdown
-- don't show if there are no entries
if #dropdown.m_sortedItems == 0 then return true end
if dropdown.m_lastParent ~= ZO_Menus then if dropdown.m_lastParent ~= ZO_Menus then
dropdown.m_lastParent = dropdown.m_dropdown:GetParent() dropdown.m_lastParent = dropdown.m_dropdown:GetParent()
dropdown.m_dropdown:SetParent(ZO_Menus) dropdown.m_dropdown:SetParent(ZO_Menus)
@ -275,7 +320,7 @@ function ScrollableDropdownHelper:DoHide()
end end
end end
function ScrollableDropdownHelper:GetMaxWidth() function ScrollableDropdownHelper:CalculateContentWidth()
local dropdown = self.dropdown local dropdown = self.dropdown
local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1) local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
@ -345,7 +390,7 @@ function LAMCreateControl.dropdown(parent, dropdownData, controlName)
if dropdownData.scrollable then if dropdownData.scrollable then
local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS
control.scrollHelper = ScrollableDropdownHelper:New(parent, control, visibleRows) control.scrollHelper = ScrollableDropdownHelper:New(LAM.util.GetTopPanel(parent), control, visibleRows)
end end
ZO_PreHook(dropdown, "UpdateItems", function(self) ZO_PreHook(dropdown, "UpdateItems", function(self)

View File

@ -4,10 +4,10 @@
getFunc = function() return db.text end, getFunc = function() return db.text end,
setFunc = function(text) db.text = text doStuff() end, setFunc = function(text) db.text = text doStuff() end,
tooltip = "Editbox's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Editbox's tooltip text.", -- or string id or function returning a string (optional)
isMultiline = true, --boolean (optional) isMultiline = true, -- boolean (optional)
isExtraWide = true, --boolean (optional) isExtraWide = true, -- boolean (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
default = defaults.text, -- default value or function that returns the default value (optional) default = defaults.text, -- default value or function that returns the default value (optional)

View File

@ -1,7 +1,7 @@
--[[headerData = { --[[headerData = {
type = "header", type = "header",
name = "My Header", -- or string id or function returning a string name = "My Header", -- or string id or function returning a string
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
reference = "MyAddonHeader" -- unique global reference to control (optional) reference = "MyAddonHeader" -- unique global reference to control (optional)
} ]] } ]]

View File

@ -11,8 +11,8 @@
iconSize = 28, -- size of the icons (optional) iconSize = 28, -- size of the icons (optional)
defaultColor = ZO_ColorDef:New("FFFFFF"), -- default color of the icons (optional) defaultColor = ZO_ColorDef:New("FFFFFF"), -- default color of the icons (optional)
width = "full", --or "half" (optional) width = "full", --or "half" (optional)
beforeShow = function(control, iconPicker) return preventShow end, --(optional) beforeShow = function(control, iconPicker) return preventShow end, -- (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
default = defaults.var, -- default value or function that returns the default value (optional) default = defaults.var, -- default value or function that returns the default value (optional)

View File

@ -4,16 +4,19 @@
displayName = "My Longer Window Title", -- or string id or function returning a string (optional) (can be useful for long addon names or if you want to colorize it) displayName = "My Longer Window Title", -- or string id or function returning a string (optional) (can be useful for long addon names or if you want to colorize it)
author = "Seerah", -- or string id or function returning a string (optional) author = "Seerah", -- or string id or function returning a string (optional)
version = "2.0", -- or string id or function returning a string (optional) version = "2.0", -- or string id or function returning a string (optional)
website = "http://www.esoui.com/downloads/info7-LibAddonMenu.html", -- URL of website where the addon can be updated (optional) website = "http://www.esoui.com/downloads/info7-LibAddonMenu.html", -- URL of website where the addon can be updated or function (optional)
feedback = "https://www.esoui.com/portal.php?uid=5815", -- URL of website where feedback/feature requests/bugs can be reported for the addon or function (optional)
translation = "https://www.esoui.com/portal.php?uid=5815", -- URL of website where translation texts of the addon can be helped with or function (optional)
donation = "http://www.esoui.com/downloads/info7-LibAddonMenu.html", -- URL of website where a donation for the addon author can be raised or function (optional)
keywords = "settings", -- additional keywords for search filter (it looks for matches in name..keywords..author) (optional) keywords = "settings", -- additional keywords for search filter (it looks for matches in name..keywords..author) (optional)
slashCommand = "/myaddon", -- will register a keybind to open to this panel (don't forget to include the slash!) (optional) slashCommand = "/myaddon", -- will register a keybind to open to this panel (don't forget to include the slash!) (optional)
registerForRefresh = true, --boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown) registerForRefresh = true, -- boolean will refresh all options controls when a setting is changed and when the panel is shown (optional)
registerForDefaults = true, --boolean (optional) (will set all options controls back to default values) registerForDefaults = true, -- boolean will set all options controls back to default values (optional)
resetFunc = function() print("defaults reset") end, --(optional) custom function to run after settings are reset to defaults resetFunc = function() print("defaults reset") end, -- custom function to run after settings are reset to defaults (optional)
} ]] } ]]
local widgetVersion = 13 local widgetVersion = 15
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("panel", widgetVersion) then return end if not LAM:RegisterWidget("panel", widgetVersion) then return end
@ -22,6 +25,8 @@ local cm = CALLBACK_MANAGER
local function RefreshPanel(control) local function RefreshPanel(control)
local panel = LAM.util.GetTopPanel(control) --callback can be fired by a single control, by the panel showing or by a nested submenu local panel = LAM.util.GetTopPanel(control) --callback can be fired by a single control, by the panel showing or by a nested submenu
if LAM.currentAddonPanel ~= panel or not LAM.currentPanelOpened then return end -- we refresh it later when the panel is opened
local panelControls = panel.controlsToRefresh local panelControls = panel.controlsToRefresh
for i = 1, #panelControls do for i = 1, #panelControls do
@ -58,8 +63,39 @@ end
local callbackRegistered = false local callbackRegistered = false
LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1 LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
local SEPARATOR = " - " local SEPARATOR = " - "
local COLORED_SEPARATOR = ZO_WHITE:Colorize(SEPARATOR)
local LINK_COLOR = ZO_ColorDef:New("5959D5") local LINK_COLOR = ZO_ColorDef:New("5959D5")
local LINK_MOUSE_OVER_COLOR = ZO_ColorDef:New("B8B8D3") local LINK_MOUSE_OVER_COLOR = ZO_ColorDef:New("B8B8D3")
local LINK_COLOR_DONATE = ZO_ColorDef:New("FFD700") -- golden
local LINK_MOUSE_OVER_COLOR_DONATE = ZO_ColorDef:New("FFF6CC")
local function CreateButtonControl(control, label, clickAction, relativeTo)
local button = wm:CreateControl(nil, control, CT_BUTTON)
button:SetClickSound("Click")
button:SetFont(LAM.util.L["PANEL_INFO_FONT"])
button:SetNormalFontColor(LINK_COLOR:UnpackRGBA())
button:SetMouseOverFontColor(LINK_MOUSE_OVER_COLOR:UnpackRGBA())
local OnClicked
local actionType = type(clickAction)
if actionType == "string" then
OnClicked = function() RequestOpenUnsafeURL(clickAction) end
elseif actionType == "function" then
OnClicked = clickAction
end
button:SetHandler("OnClicked", OnClicked)
if relativeTo then
button:SetAnchor(TOPLEFT, relativeTo, TOPRIGHT, 0, 0)
button:SetText(COLORED_SEPARATOR .. label)
else
button:SetAnchor(TOPLEFT, control.label, BOTTOMLEFT, 0, -2)
button:SetText(label)
end
button:SetDimensions(button:GetLabelControl():GetTextDimensions())
return button
end
function LAMCreateControl.panel(parent, panelData, controlName) function LAMCreateControl.panel(parent, panelData, controlName)
local control = wm:CreateControl(controlName, parent, CT_CONTROL) local control = wm:CreateControl(controlName, parent, CT_CONTROL)
@ -69,6 +105,7 @@ function LAMCreateControl.panel(parent, panelData, controlName)
label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 4) label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 4)
label:SetText(LAM.util.GetStringFromValue(panelData.displayName or panelData.name)) label:SetText(LAM.util.GetStringFromValue(panelData.displayName or panelData.name))
local previousInfoControl
if panelData.author or panelData.version then if panelData.author or panelData.version then
control.info = wm:CreateControl(nil, control, CT_LABEL) control.info = wm:CreateControl(nil, control, CT_LABEL)
local info = control.info local info = control.info
@ -83,26 +120,30 @@ function LAMCreateControl.panel(parent, panelData, controlName)
output[#output + 1] = zo_strformat(LAM.util.L["VERSION"], LAM.util.GetStringFromValue(panelData.version)) output[#output + 1] = zo_strformat(LAM.util.L["VERSION"], LAM.util.GetStringFromValue(panelData.version))
end end
info:SetText(table.concat(output, SEPARATOR)) info:SetText(table.concat(output, SEPARATOR))
previousInfoControl = info
end end
if panelData.website then if panelData.website then
control.website = wm:CreateControl(nil, control, CT_BUTTON) control.website = CreateButtonControl(control, LAM.util.L["WEBSITE"], panelData.website, previousInfoControl)
local website = control.website previousInfoControl = control.website
website:SetClickSound("Click")
website:SetFont(LAM.util.L["PANEL_INFO_FONT"])
website:SetNormalFontColor(LINK_COLOR:UnpackRGBA())
website:SetMouseOverFontColor(LINK_MOUSE_OVER_COLOR:UnpackRGBA())
if(control.info) then
website:SetAnchor(TOPLEFT, control.info, TOPRIGHT, 0, 0)
website:SetText(string.format("|cffffff%s|r%s", SEPARATOR, LAM.util.L["WEBSITE"]))
else
website:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
website:SetText(LAM.util.L["WEBSITE"])
end end
website:SetDimensions(website:GetLabelControl():GetTextDimensions())
website:SetHandler("OnClicked", function() if panelData.feedback then
RequestOpenUnsafeURL(panelData.website) control.feedback = CreateButtonControl(control, LAM.util.L["FEEDBACK"], panelData.feedback, previousInfoControl)
end) previousInfoControl = control.feedback
end
if panelData.translation then
control.translation = CreateButtonControl(control, LAM.util.L["TRANSLATION"], panelData.translation, previousInfoControl)
previousInfoControl = control.translation
end
if panelData.donation then
control.donation = CreateButtonControl(control, LAM.util.L["DONATION"], panelData.donation, previousInfoControl)
local donation = control.donation
previousInfoControl = donation
donation:SetNormalFontColor(LINK_COLOR_DONATE:UnpackRGBA())
donation:SetMouseOverFontColor(LINK_MOUSE_OVER_COLOR_DONATE:UnpackRGBA())
end end
control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer") control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
@ -119,6 +160,7 @@ function LAMCreateControl.panel(parent, panelData, controlName)
end end
control.ForceDefaults = ForceDefaults control.ForceDefaults = ForceDefaults
control.RefreshPanel = LAM.util.RequestRefreshIfNeeded
control.data = panelData control.data = panelData
control.controlsToRefresh = {} control.controlsToRefresh = {}

View File

@ -5,13 +5,14 @@
setFunc = function(value) db.var = value doStuff() end, setFunc = function(value) db.var = value doStuff() end,
min = 0, min = 0,
max = 20, max = 20,
step = 1, --(optional) step = 1, -- (optional)
clampInput = true, -- boolean, if set to false the input won't clamp to min and max and allow any number instead (optional) clampInput = true, -- boolean, if set to false the input won't clamp to min and max and allow any number instead (optional)
clampFunction = function(value, min, max) return math.max(math.min(value, max), min) end, -- function that is called to clamp the value (optional)
decimals = 0, -- when specified the input value is rounded to the specified number of decimals (optional) decimals = 0, -- when specified the input value is rounded to the specified number of decimals (optional)
autoSelect = false, -- boolean, automatically select everything in the text input field when it gains focus (optional) autoSelect = false, -- boolean, automatically select everything in the text input field when it gains focus (optional)
inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional) inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional)
tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
disabled = function() return db.someBooleanSetting end, --or boolean (optional) disabled = function() return db.someBooleanSetting end, --or boolean (optional)
warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional) warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional) requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
@ -19,7 +20,7 @@
reference = "MyAddonSlider" -- unique global reference to control (optional) reference = "MyAddonSlider" -- unique global reference to control (optional)
} ]] } ]]
local widgetVersion = 12 local widgetVersion = 13
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("slider", widgetVersion) then return end if not LAM:RegisterWidget("slider", widgetVersion) then return end
@ -30,6 +31,10 @@ local function RoundDecimalToPlace(d, place)
return tonumber(strformat("%." .. tostring(place) .. "f", d)) return tonumber(strformat("%." .. tostring(place) .. "f", d))
end end
local function ClampValue(value, min, max)
return math.max(math.min(value, max), min)
end
local function UpdateDisabled(control) local function UpdateDisabled(control)
local disable local disable
if type(control.data.disabled) == "function" then if type(control.data.disabled) == "function" then
@ -62,7 +67,8 @@ local function UpdateValue(control, forceDefault, value)
value = RoundDecimalToPlace(value, control.data.decimals) value = RoundDecimalToPlace(value, control.data.decimals)
end end
if control.data.clampInput ~= false then if control.data.clampInput ~= false then
value = math.max(math.min(value, control.data.max), control.data.min) local clamp = control.data.clampFunction or ClampValue
value = clamp(value, control.data.min, control.data.max)
end end
control.data.setFunc(value) control.data.setFunc(value)
--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
@ -182,7 +188,9 @@ function LAMCreateControl.slider(parent, sliderData, controlName)
HandleValueChanged(value) HandleValueChanged(value)
end) end)
slider:SetHandler("OnSliderReleased", function(self, value) slider:SetHandler("OnSliderReleased", function(self, value)
if self:GetEnabled() then
control:UpdateValue(false, value) control:UpdateValue(false, value)
end
end) end)
slider:SetHandler("OnMouseWheel", function(self, value) slider:SetHandler("OnMouseWheel", function(self, value)
if(not self:GetEnabled()) then return end if(not self:GetEnabled()) then return end

View File

@ -1,20 +1,61 @@
--[[submenuData = { --[[submenuData = {
type = "submenu", type = "submenu",
name = "Submenu Title", -- or string id or function returning a string name = "Submenu Title", -- or string id or function returning a string
tooltip = "My submenu tooltip", -- -- or string id or function returning a string (optional) icon = "path/to/my/icon.dds", -- or function returning a string (optional)
controls = {sliderData, buttonData} --(optional) used by LAM iconTextureCoords = {left, right, top, bottom}, -- or function returning a table (optional)
reference = "MyAddonSubmenu" --(optional) unique global reference to control tooltip = "My submenu tooltip", -- or string id or function returning a string (optional)
controls = {sliderData, buttonData} -- used by LAM (optional)
disabled = function() return db.someBooleanSetting end, -- or boolean (optional)
disabledLabel = function() return db.someBooleanSetting end, -- or boolean (optional)
reference = "MyAddonSubmenu" -- unique global reference to control (optional)
} ]] } ]]
local widgetVersion = 11 local widgetVersion = 13
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")
if not LAM:RegisterWidget("submenu", widgetVersion) then return end if not LAM:RegisterWidget("submenu", widgetVersion) then return end
local wm = WINDOW_MANAGER local wm = WINDOW_MANAGER
local am = ANIMATION_MANAGER local am = ANIMATION_MANAGER
local ICON_SIZE = 32
local GetDefaultValue = LAM.util.GetDefaultValue
local GetColorForState = LAM.util.GetColorForState
local function UpdateDisabled(control)
local disable = GetDefaultValue(control.data.disabled)
if disable ~= control.disabled then
local color = GetColorForState(disable)
if disable and control.open then
control.open = false
control.animation:PlayFromStart()
end
control.arrow:SetColor(color:UnpackRGBA())
control.disabled = disable
end
local disableLabel = control.disabled or GetDefaultValue(control.data.disabledLabel)
if disableLabel ~= control.disabledLabel then
local color = GetColorForState(disableLabel)
control.label:SetColor(color:UnpackRGBA())
if(control.icon) then
control.icon:SetDesaturation(disableLabel and 1 or 0)
end
control.disabledLabel = disableLabel
end
end
local function UpdateValue(control) local function UpdateValue(control)
control.label:SetText(LAM.util.GetStringFromValue(control.data.name)) control.label:SetText(LAM.util.GetStringFromValue(control.data.name))
if control.icon then
control.icon:SetTexture(GetDefaultValue(control.data.icon))
if(control.data.iconTextureCoords) then
local coords = GetDefaultValue(control.data.iconTextureCoords)
control.icon:SetTextureCoords(unpack(coords))
end
end
if control.data.tooltip then if control.data.tooltip then
control.label.data.tooltipText = LAM.util.GetStringFromValue(control.data.tooltip) control.label.data.tooltipText = LAM.util.GetStringFromValue(control.data.tooltip)
end end
@ -22,8 +63,9 @@ end
local function AnimateSubmenu(clicked) local function AnimateSubmenu(clicked)
local control = clicked:GetParent() local control = clicked:GetParent()
control.open = not control.open if control.disabled then return end
control.open = not control.open
if control.open then if control.open then
control.animation:PlayFromStart() control.animation:PlayFromStart()
else else
@ -39,30 +81,55 @@ function LAMCreateControl.submenu(parent, submenuData, controlName)
control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel") control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
local label = control.label local label = control.label
label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
label:SetDimensions(width, 30)
label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
label:SetText(LAM.util.GetStringFromValue(submenuData.name)) label:SetText(LAM.util.GetStringFromValue(submenuData.name))
label:SetMouseEnabled(true) label:SetMouseEnabled(true)
if submenuData.icon then
control.icon = wm:CreateControl(nil, control, CT_TEXTURE)
local icon = control.icon
icon:SetTexture(GetDefaultValue(submenuData.icon))
if(submenuData.iconTextureCoords) then
local coords = GetDefaultValue(submenuData.iconTextureCoords)
icon:SetTextureCoords(unpack(coords))
end
icon:SetDimensions(ICON_SIZE, ICON_SIZE)
icon:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
icon:SetMouseEnabled(true)
icon:SetDrawLayer(DL_CONTROLS)
label:SetAnchor(TOP, control, TOP, 0, 5, ANCHOR_CONSTRAINS_Y)
label:SetAnchor(LEFT, icon, RIGHT, 10, 0, ANCHOR_CONSTRAINS_X)
label:SetDimensions(width - ICON_SIZE - 5, 30)
else
label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
label:SetDimensions(width, 30)
end
if submenuData.tooltip then if submenuData.tooltip then
label.data = {tooltipText = LAM.util.GetStringFromValue(submenuData.tooltip)} label.data = {tooltipText = LAM.util.GetStringFromValue(submenuData.tooltip)}
label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
if control.icon then
control.icon.data = label.data
control.icon:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
control.icon:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
end
end end
control.scroll = wm:CreateControl(nil, control, CT_SCROLL) control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
local scroll = control.scroll local scroll = control.scroll
scroll:SetParent(control) scroll:SetParent(control)
scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10) scroll:SetAnchor(TOPLEFT, control.icon or label, BOTTOMLEFT, 0, 10)
scroll:SetDimensionConstraints(width + 5, 0, width + 5, 0) scroll:SetDimensionConstraints(width + 5, 0, width + 5, 0)
control.bg = wm:CreateControl(nil, label, CT_BACKDROP) control.bg = wm:CreateControl(nil, control.icon or label, CT_BACKDROP)
local bg = control.bg local bg = control.bg
bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5) bg:SetAnchor(TOPLEFT, control.icon or label, TOPLEFT, -5, -5)
bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0) bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16) bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds") bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
bg:SetInsets(16, 16, -16, -16) bg:SetInsets(16, 16, -16, -16)
bg:SetDrawLayer(DL_BACKGROUND)
control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE) control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
local arrow = control.arrow local arrow = control.arrow
@ -78,6 +145,9 @@ function LAMCreateControl.submenu(parent, submenuData, controlName)
control:SetResizeToFitDescendents(true) control:SetResizeToFitDescendents(true)
control.open = false control.open = false
label:SetHandler("OnMouseUp", AnimateSubmenu) label:SetHandler("OnMouseUp", AnimateSubmenu)
if(control.icon) then
control.icon:SetHandler("OnMouseUp", AnimateSubmenu)
end
animation:SetHandler("OnStop", function(self, completedPlaying) animation:SetHandler("OnStop", function(self, completedPlaying)
scroll:SetResizeToFitDescendents(control.open) scroll:SetResizeToFitDescendents(control.open)
if control.open then if control.open then
@ -101,6 +171,10 @@ function LAMCreateControl.submenu(parent, submenuData, controlName)
btmToggle:SetHandler("OnMouseUp", AnimateSubmenu) btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
control.UpdateValue = UpdateValue control.UpdateValue = UpdateValue
if submenuData.disabled ~= nil or submenuData.disabledLabel ~= nil then
control.UpdateDisabled = UpdateDisabled
control:UpdateDisabled()
end
LAM.util.RegisterForRefreshIfNeeded(control) LAM.util.RegisterForRefreshIfNeeded(control)

View File

@ -1,14 +1,14 @@
--[[textureData = { --[[textureData = {
type = "texture", type = "texture",
image = "file/path.dds", image = "file/path.dds",
imageWidth = 64, --max of 250 for half width, 510 for full imageWidth = 64, -- max of 250 for half width, 510 for full
imageHeight = 32, --max of 100 imageHeight = 32, -- max of 100
tooltip = "Image's tooltip text.", -- or string id or function returning a string (optional) tooltip = "Image's tooltip text.", -- or string id or function returning a string (optional)
width = "full", --or "half" (optional) width = "full", -- or "half" (optional)
reference = "MyAddonTexture" --(optional) unique global reference to control reference = "MyAddonTexture" -- unique global reference to control (optional)
} ]] } ]]
--add texture coords support? -- TODO: add texture coords support?
local widgetVersion = 9 local widgetVersion = 9
local LAM = LibStub("LibAddonMenu-2.0") local LAM = LibStub("LibAddonMenu-2.0")

View File

@ -3,7 +3,7 @@
-- LibStub developed for World of Warcraft by above members of the WowAce community. -- LibStub developed for World of Warcraft by above members of the WowAce community.
-- Ported to Elder Scrolls Online by Seerah -- Ported to Elder Scrolls Online by Seerah
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 4 local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 5
local LibStub = _G[LIBSTUB_MAJOR] local LibStub = _G[LIBSTUB_MAJOR]
local strformat = string.format local strformat = string.format