Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
3f214a3cd3 | |||
d9ab607b4c | |||
92882f9de1 | |||
a64f7525d0 | |||
fa78082738 | |||
9b655c1848 | |||
fba862a1ef | |||
c5a82f86c9 | |||
341f07a0f6 | |||
bead07a0cf | |||
407dc14298 | |||
7b9de40e57 | |||
450cad90b9 | |||
739352c641 | |||
6ccaa69b5a | |||
6ae87cea64 | |||
f9d3cf6e84 | |||
0d5248671f | |||
|
634f7b5c6d | ||
|
affde86fa9 | ||
53bc660b7c | |||
|
ec7939be37 | ||
de1cb88ca8 | |||
|
176a0ccf91 | ||
|
fde8966292 | ||
|
90332bac93 | ||
|
014300b239 | ||
b55d263f25 | |||
7c530dc0a1 | |||
c9ac569694 | |||
|
35abf9337b | ||
c7d11b3e44 | |||
|
af3a473fe2 | ||
|
dfbc2feeb4 | ||
645fc569f3 | |||
|
8a18c59c49 | ||
|
df150a12ab |
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"url": "https://drone.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/"
|
|
||||||
}
|
|
58
.drone.yml
58
.drone.yml
@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: default
|
|
||||||
|
|
||||||
clone:
|
|
||||||
disable: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: clone
|
|
||||||
image: alpine/git
|
|
||||||
commands:
|
|
||||||
- git clone https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo.git sources
|
|
||||||
- cd sources && git checkout $DRONE_COMMIT
|
|
||||||
|
|
||||||
- name: lint
|
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- apk update
|
|
||||||
- apk add --no-cache build-base curl unzip
|
|
||||||
- apk add --no-cache lua5.1 lua5.1-dev luarocks5.1
|
|
||||||
- luarocks-5.1 install luacheck
|
|
||||||
- cd sources
|
|
||||||
- luacheck ./*.lua
|
|
||||||
|
|
||||||
- name: build
|
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- apk update && apk add --no-cache zip
|
|
||||||
# Delete unneeded files/dirs
|
|
||||||
- rm -rf sources/.git
|
|
||||||
- rm -f sources/.drone.status
|
|
||||||
- rm -f sources/.drone.yml
|
|
||||||
- rm -f sources/.luacheckrc
|
|
||||||
# Set Version and AddonVersion
|
|
||||||
- export VERSION=$DRONE_TAG
|
|
||||||
- export ADDON_VERSION=$(echo $DRONE_TAG | sed -E 's/(0|)\.//g')
|
|
||||||
- sed -i "s/0.123456789/$VERSION/g" sources/AchievementInfoCommon.lua
|
|
||||||
- sed -i "s/0.123456789/$VERSION/g" sources/AchievementInfo.txt
|
|
||||||
- sed -i "s/0.123456789/$ADDON_VERSION/g" sources/AchievementInfo.txt
|
|
||||||
# Rename and zip
|
|
||||||
- mv sources AchievementInfo
|
|
||||||
- zip -r "AchievementInfo-$DRONE_TAG.zip" ./AchievementInfo
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- tag
|
|
||||||
|
|
||||||
- name: release
|
|
||||||
image: plugins/gitea-release
|
|
||||||
settings:
|
|
||||||
base_url: https://git.f-brinker.de
|
|
||||||
api_key:
|
|
||||||
from_secret: gitea_token
|
|
||||||
files: ./*.zip
|
|
||||||
title: AchievementInfo ${DRONE_TAG}
|
|
||||||
note: AchievementInfo/CHANGELOG.md
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- tag
|
|
55
.gitea/workflows/build.yaml
Normal file
55
.gitea/workflows/build.yaml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
name: Workflow
|
||||||
|
run-name: ${{ gitea.actor }} is linting and creating a new release on tag pushes 🚀
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
Linting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Run Luacheck linter
|
||||||
|
uses: lunarmodules/luacheck@v1
|
||||||
|
|
||||||
|
Release:
|
||||||
|
needs: [Linting]
|
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/') }} # only for tags
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
Version: ${{ gitea.ref_name }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: sources
|
||||||
|
- name: Delete unneeded files/dirs
|
||||||
|
run: |
|
||||||
|
rm -rf sources/.git
|
||||||
|
rm -rf sources/.gitea
|
||||||
|
rm -rf sources/screenshots
|
||||||
|
rm -f sources/.luacheckrc
|
||||||
|
- name: Set Version and AddonVersion
|
||||||
|
run: |
|
||||||
|
echo "Version: ${{ env.Version }}"
|
||||||
|
export ADDON_VERSION=$(echo ${{ env.Version }} | sed -E 's/(0|)\.//g')
|
||||||
|
sed -i "s/0.123456789/${{ env.Version }}/g" sources/AchievementInfoCommon.lua
|
||||||
|
sed -i "s/0.123456789/${{ env.Version }}/g" sources/AchievementInfo.txt
|
||||||
|
sed -i "s/0.123456789/$ADDON_VERSION/g" sources/AchievementInfo.txt
|
||||||
|
- name: Rename and zip
|
||||||
|
run: |
|
||||||
|
mv sources AchievementInfo
|
||||||
|
zip -r "AchievementInfo-${{ env.Version }}.zip" ./AchievementInfo
|
||||||
|
- name: Create release
|
||||||
|
id: create_release
|
||||||
|
uses: akkuman/gitea-release-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.token }}
|
||||||
|
name: "AchievementInfo ${{ env.Version }}"
|
||||||
|
tag_name: "${{ env.Version }}"
|
||||||
|
body_path: AchievementInfo/CHANGELOG.md
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
sha256sum: true
|
||||||
|
files: |-
|
||||||
|
*.zip
|
@ -17,7 +17,8 @@ read_globals = {
|
|||||||
"EVENT_ACHIEVEMENT_UPDATED",
|
"EVENT_ACHIEVEMENT_UPDATED",
|
||||||
"EVENT_ADD_ON_LOADED",
|
"EVENT_ADD_ON_LOADED",
|
||||||
"EVENT_MANAGER",
|
"EVENT_MANAGER",
|
||||||
"LINK_STYLE_BRACKET",
|
"LINK_STYLE_BRACKETS",
|
||||||
"zo_callLater",
|
"zo_callLater",
|
||||||
|
"zo_strformat",
|
||||||
"ZO_SavedVars",
|
"ZO_SavedVars",
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ function AchievementInfo.initialize(_, addOnName)
|
|||||||
AchievementInfo.hijackedFirstLoad = true
|
AchievementInfo.hijackedFirstLoad = true
|
||||||
|
|
||||||
-- Load Saved Variables
|
-- Load Saved Variables
|
||||||
|
AchievementInfo.useAccountWideSettings = AchievementInfo.loadUseAccountWideSettings()
|
||||||
AchievementInfo.savedVars = AchievementInfo.loadSavedVars()
|
AchievementInfo.savedVars = AchievementInfo.loadSavedVars()
|
||||||
|
|
||||||
-- Load Language Data
|
-- Load Language Data
|
||||||
|
@ -5,13 +5,10 @@
|
|||||||
## Author: |c87B7CCAsto|r, @Astarax
|
## Author: |c87B7CCAsto|r, @Astarax
|
||||||
## Contact: mail@coded-with-heart.com
|
## Contact: mail@coded-with-heart.com
|
||||||
|
|
||||||
## APIVersion: 100029
|
## APIVersion: 101044
|
||||||
## SavedVariables: ACHIEVEMENT_INFO_DB
|
## SavedVariables: ACHIEVEMENT_INFO_DB ACHIEVEMENT_INFO_DB_USE_AW
|
||||||
|
|
||||||
## OptionalDependsOn: LibAddonMenu-2.0
|
## DependsOn: LibAddonMenu-2.0
|
||||||
|
|
||||||
## Libraries:
|
|
||||||
Libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
|
|
||||||
|
|
||||||
## Helper:
|
## Helper:
|
||||||
AchievementInfoCommon.lua
|
AchievementInfoCommon.lua
|
||||||
|
@ -49,7 +49,7 @@ function AchievementInfo.onAchievementUpdated(_, achId)
|
|||||||
local percentageStep = false
|
local percentageStep = false
|
||||||
local percentageStepSize = AchievementInfo.settingGet("genShowUpdateSteps")
|
local percentageStepSize = AchievementInfo.settingGet("genShowUpdateSteps")
|
||||||
|
|
||||||
local link = GetAchievementLink(achId, LINK_STYLE_BRACKET)
|
local link = GetAchievementLink(achId, LINK_STYLE_BRACKETS)
|
||||||
local catName = "/"
|
local catName = "/"
|
||||||
|
|
||||||
if categoryId ~= false then
|
if categoryId ~= false then
|
||||||
@ -67,13 +67,18 @@ function AchievementInfo.onAchievementUpdated(_, achId)
|
|||||||
tmpOutput = tmpOutput .. ", "
|
tmpOutput = tmpOutput .. ", "
|
||||||
end
|
end
|
||||||
|
|
||||||
tmpOutput = tmpOutput .. description .. " "
|
tmpOutput = tmpOutput .. zo_strformat("<<1>>", description) .. " "
|
||||||
tmpOutput = tmpOutput .. AchievementInfo.calcCriteriaColor(numCompleted, numRequired) .. numCompleted .. "|r"
|
tmpOutput = tmpOutput .. AchievementInfo.calcCriteriaColor(numCompleted, numRequired) .. numCompleted .. "|r"
|
||||||
tmpOutput = tmpOutput .. AchievementInfo.clrDefault .. "/" .. "|r"
|
tmpOutput = tmpOutput .. AchievementInfo.clrDefault .. "/" .. "|r"
|
||||||
tmpOutput = tmpOutput .. AchievementInfo.clrCriteriaComplete .. numRequired .. "|r"
|
tmpOutput = tmpOutput .. AchievementInfo.clrCriteriaComplete .. numRequired .. "|r"
|
||||||
tmpOutput = tmpOutput .. AchievementInfo.clrDefault
|
tmpOutput = tmpOutput .. AchievementInfo.clrDefault
|
||||||
|
|
||||||
if AchievementInfo.settingGet("genShowOpenDetailsOnly") == true and numCompleted ~= numRequired then
|
if AchievementInfo.settingGet("genShowOpenDetailsOnly") == true then
|
||||||
|
if numCompleted ~= numRequired then
|
||||||
|
detailOutput[detailOutputCount] = tmpOutput
|
||||||
|
detailOutputCount = detailOutputCount + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
detailOutput[detailOutputCount] = tmpOutput
|
detailOutput[detailOutputCount] = tmpOutput
|
||||||
detailOutputCount = detailOutputCount + 1
|
detailOutputCount = detailOutputCount + 1
|
||||||
end
|
end
|
||||||
|
@ -35,6 +35,9 @@ LANG_STORE.EN.SettingsOption.AddOnEnabled = "AddOn enabled"
|
|||||||
LANG_STORE.EN.SettingsOption.AddOnEnabledTooltip = "Enable or disable this AddOn"
|
LANG_STORE.EN.SettingsOption.AddOnEnabledTooltip = "Enable or disable this AddOn"
|
||||||
LANG_STORE.EN.SettingsOption.AddOnEnabledWarning = "Only the output messages can be disabled here"
|
LANG_STORE.EN.SettingsOption.AddOnEnabledWarning = "Only the output messages can be disabled here"
|
||||||
|
|
||||||
|
LANG_STORE.EN.SettingsOption.AccountWideEnabled = "Use account-wide Settings"
|
||||||
|
LANG_STORE.EN.SettingsOption.AccountWideEnabledTooltip = "Use and edit the same settings for all characters"
|
||||||
|
|
||||||
LANG_STORE.EN.SettingsOption.ShowEveryUpdate = "Show every update"
|
LANG_STORE.EN.SettingsOption.ShowEveryUpdate = "Show every update"
|
||||||
LANG_STORE.EN.SettingsOption.ShowEveryUpdateTooltip = "Shows a message on every status update of an achievement. Otherwise the messages appear only in steps of x%"
|
LANG_STORE.EN.SettingsOption.ShowEveryUpdateTooltip = "Shows a message on every status update of an achievement. Otherwise the messages appear only in steps of x%"
|
||||||
|
|
||||||
@ -86,6 +89,9 @@ LANG_STORE.DE.SettingsOption.AddOnEnabled = "AddOn aktiviert"
|
|||||||
LANG_STORE.DE.SettingsOption.AddOnEnabledTooltip = "Aktiviere oder deaktiviere dieses AddOn"
|
LANG_STORE.DE.SettingsOption.AddOnEnabledTooltip = "Aktiviere oder deaktiviere dieses AddOn"
|
||||||
LANG_STORE.DE.SettingsOption.AddOnEnabledWarning = "An dieser Stelle können nur die Ausgaben deaktiviert werden."
|
LANG_STORE.DE.SettingsOption.AddOnEnabledWarning = "An dieser Stelle können nur die Ausgaben deaktiviert werden."
|
||||||
|
|
||||||
|
LANG_STORE.DE.SettingsOption.AccountWideEnabled = "Accountübergreifende Einstellungen"
|
||||||
|
LANG_STORE.DE.SettingsOption.AccountWideEnabledTooltip = "Benutze und speichere die Einstellungen für alle Charaktere"
|
||||||
|
|
||||||
LANG_STORE.DE.SettingsOption.ShowEveryUpdate = "Zeige alle Fortschritte"
|
LANG_STORE.DE.SettingsOption.ShowEveryUpdate = "Zeige alle Fortschritte"
|
||||||
LANG_STORE.DE.SettingsOption.ShowEveryUpdateTooltip = "Zeigt bei jeder Aktualisierung eines Erfolgs einen Hinweis. Alternativ wird nur in x% Schritten ein Status ausgegeben"
|
LANG_STORE.DE.SettingsOption.ShowEveryUpdateTooltip = "Zeigt bei jeder Aktualisierung eines Erfolgs einen Hinweis. Alternativ wird nur in x% Schritten ein Status ausgegeben"
|
||||||
|
|
||||||
@ -138,6 +144,9 @@ LANG_STORE.FR.SettingsOption.AddOnEnabled = "Extension activée"
|
|||||||
LANG_STORE.FR.SettingsOption.AddOnEnabledTooltip = "Active ou désactive cette extension"
|
LANG_STORE.FR.SettingsOption.AddOnEnabledTooltip = "Active ou désactive cette extension"
|
||||||
LANG_STORE.FR.SettingsOption.AddOnEnabledWarning = "Seul les messages sortants peuvent être désactivés"
|
LANG_STORE.FR.SettingsOption.AddOnEnabledWarning = "Seul les messages sortants peuvent être désactivés"
|
||||||
|
|
||||||
|
LANG_STORE.FR.SettingsOption.AccountWideEnabled = LANG_STORE.EN.SettingsOption.AccountWideEnabled
|
||||||
|
LANG_STORE.FR.SettingsOption.AccountWideEnabledTooltip = LANG_STORE.EN.SettingsOption.AccountWideEnabledTooltip
|
||||||
|
|
||||||
LANG_STORE.FR.SettingsOption.ShowEveryUpdate = "Affichage de chaque mise à jour"
|
LANG_STORE.FR.SettingsOption.ShowEveryUpdate = "Affichage de chaque mise à jour"
|
||||||
LANG_STORE.FR.SettingsOption.ShowEveryUpdateTooltip = "Affiche un message pour chaque mise à jour d'un succès. Le reste du temps les messages n'apparaissent que sous forme de plage de x%"
|
LANG_STORE.FR.SettingsOption.ShowEveryUpdateTooltip = "Affiche un message pour chaque mise à jour d'un succès. Le reste du temps les messages n'apparaissent que sous forme de plage de x%"
|
||||||
|
|
||||||
|
@ -5,6 +5,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Function to determine if Account Wide Settings should be used
|
||||||
|
function AchievementInfo.loadUseAccountWideSettings()
|
||||||
|
return ZO_SavedVars:New("ACHIEVEMENT_INFO_DB_USE_AW", 1, nil, {
|
||||||
|
enabled = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Function to set and load the Saved Variables
|
-- Function to set and load the Saved Variables
|
||||||
function AchievementInfo.loadSavedVars()
|
function AchievementInfo.loadSavedVars()
|
||||||
local defaults = {
|
local defaults = {
|
||||||
@ -36,9 +45,14 @@ function AchievementInfo.loadSavedVars()
|
|||||||
cat20 = true,
|
cat20 = true,
|
||||||
cat21 = true,
|
cat21 = true,
|
||||||
cat22 = true,
|
cat22 = true,
|
||||||
|
-- ... new one default to true
|
||||||
devDebug = false
|
devDebug = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if AchievementInfo.useAccountWideSettings["enabled"] == true then
|
||||||
|
return ZO_SavedVars:NewAccountWide("ACHIEVEMENT_INFO_DB", 1, nil, defaults)
|
||||||
|
end
|
||||||
|
|
||||||
return ZO_SavedVars:New("ACHIEVEMENT_INFO_DB", 1, nil, defaults)
|
return ZO_SavedVars:New("ACHIEVEMENT_INFO_DB", 1, nil, defaults)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -51,7 +65,7 @@ function AchievementInfo.createSettingsPanel()
|
|||||||
name = AchievementInfo.name,
|
name = AchievementInfo.name,
|
||||||
displayName = AchievementInfo.clrDefault .. AchievementInfo.name,
|
displayName = AchievementInfo.clrDefault .. AchievementInfo.name,
|
||||||
author = AchievementInfo.author,
|
author = AchievementInfo.author,
|
||||||
version = string.format("%.1f", AchievementInfo.version),
|
version = string.format("%.2f", AchievementInfo.version),
|
||||||
slashCommand = "/achievementInfo"
|
slashCommand = "/achievementInfo"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +83,21 @@ function AchievementInfo.createSettingsPanel()
|
|||||||
warning = LANG.SettingsOption.AddOnEnabledWarning
|
warning = LANG.SettingsOption.AddOnEnabledWarning
|
||||||
},
|
},
|
||||||
[3] = {
|
[3] = {
|
||||||
|
type = "checkbox",
|
||||||
|
name = LANG.SettingsOption.AccountWideEnabled,
|
||||||
|
tooltip = LANG.SettingsOption.AccountWideEnabledTooltip,
|
||||||
|
getFunc = function() return AchievementInfo.useAccountWideSettings["enabled"] end,
|
||||||
|
setFunc = function() AchievementInfo.toggleAccountWideSettings() end,
|
||||||
|
requiresReload = true
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
type = "checkbox",
|
type = "checkbox",
|
||||||
name = LANG.SettingsOption.ShowEveryUpdate,
|
name = LANG.SettingsOption.ShowEveryUpdate,
|
||||||
tooltip = LANG.SettingsOption.ShowEveryUpdateTooltip,
|
tooltip = LANG.SettingsOption.ShowEveryUpdateTooltip,
|
||||||
getFunc = function() return AchievementInfo.settingGet("genShowEveryUpdate") end,
|
getFunc = function() return AchievementInfo.settingGet("genShowEveryUpdate") end,
|
||||||
setFunc = function() AchievementInfo.settingToogle("genShowEveryUpdate") end
|
setFunc = function() AchievementInfo.settingToogle("genShowEveryUpdate") end
|
||||||
},
|
},
|
||||||
[4] = {
|
[5] = {
|
||||||
type = "slider",
|
type = "slider",
|
||||||
name = LANG.SettingsOption.ShowUpdateSteps,
|
name = LANG.SettingsOption.ShowUpdateSteps,
|
||||||
tooltip = LANG.SettingsOption.ShowUpdateStepsTooltip,
|
tooltip = LANG.SettingsOption.ShowUpdateStepsTooltip,
|
||||||
@ -86,21 +108,21 @@ function AchievementInfo.createSettingsPanel()
|
|||||||
setFunc = function(value) AchievementInfo.settingSet("genShowUpdateSteps", value) end,
|
setFunc = function(value) AchievementInfo.settingSet("genShowUpdateSteps", value) end,
|
||||||
default = 25
|
default = 25
|
||||||
},
|
},
|
||||||
[5] = {
|
[6] = {
|
||||||
type = "checkbox",
|
type = "checkbox",
|
||||||
name = LANG.SettingsOption.ShowDetails,
|
name = LANG.SettingsOption.ShowDetails,
|
||||||
tooltip = LANG.SettingsOption.ShowDetailsTooltip,
|
tooltip = LANG.SettingsOption.ShowDetailsTooltip,
|
||||||
getFunc = function() return AchievementInfo.settingGet("genShowDetails") end,
|
getFunc = function() return AchievementInfo.settingGet("genShowDetails") end,
|
||||||
setFunc = function() AchievementInfo.settingToogle("genShowDetails") end
|
setFunc = function() AchievementInfo.settingToogle("genShowDetails") end
|
||||||
},
|
},
|
||||||
[6] = {
|
[7] = {
|
||||||
type = "checkbox",
|
type = "checkbox",
|
||||||
name = LANG.SettingsOption.ShowOpenDetailsOnly,
|
name = LANG.SettingsOption.ShowOpenDetailsOnly,
|
||||||
tooltip = LANG.SettingsOption.ShowOpenDetailsOnlyTooltip,
|
tooltip = LANG.SettingsOption.ShowOpenDetailsOnlyTooltip,
|
||||||
getFunc = function() return AchievementInfo.settingGet("genShowOpenDetailsOnly") end,
|
getFunc = function() return AchievementInfo.settingGet("genShowOpenDetailsOnly") end,
|
||||||
setFunc = function() AchievementInfo.settingToogle("genShowOpenDetailsOnly") end
|
setFunc = function() AchievementInfo.settingToogle("genShowOpenDetailsOnly") end
|
||||||
},
|
},
|
||||||
[7] = {
|
[8] = {
|
||||||
type = "checkbox",
|
type = "checkbox",
|
||||||
name = LANG.SettingsOption.OneElementPerLine,
|
name = LANG.SettingsOption.OneElementPerLine,
|
||||||
tooltip = LANG.SettingsOption.OneElementPerLineTooltip,
|
tooltip = LANG.SettingsOption.OneElementPerLineTooltip,
|
||||||
@ -108,11 +130,11 @@ function AchievementInfo.createSettingsPanel()
|
|||||||
setFunc = function() AchievementInfo.settingToogle("genOnePerLine") end,
|
setFunc = function() AchievementInfo.settingToogle("genOnePerLine") end,
|
||||||
warning = LANG.SettingsOption.OneElementPerLineWarning
|
warning = LANG.SettingsOption.OneElementPerLineWarning
|
||||||
},
|
},
|
||||||
[8] = {
|
[9] = {
|
||||||
type = "header",
|
type = "header",
|
||||||
name = AchievementInfo.clrSettingsHeader .. LANG.SettingsHeader.Categories
|
name = AchievementInfo.clrSettingsHeader .. LANG.SettingsHeader.Categories
|
||||||
},
|
},
|
||||||
[9] = {
|
[10] = {
|
||||||
type = "description",
|
type = "description",
|
||||||
text = LANG.SettingsHeader.CategoriesDescription .. ":"
|
text = LANG.SettingsHeader.CategoriesDescription .. ":"
|
||||||
}
|
}
|
||||||
@ -128,7 +150,7 @@ function AchievementInfo.createSettingsPanel()
|
|||||||
type = "checkbox",
|
type = "checkbox",
|
||||||
name = catName,
|
name = catName,
|
||||||
tooltip = LANG.SettingsOption.CategoryTooltip .. " '" .. catName .. "'",
|
tooltip = LANG.SettingsOption.CategoryTooltip .. " '" .. catName .. "'",
|
||||||
getFunc = function() return AchievementInfo.settingGet("cat"..i) end,
|
getFunc = function() return AchievementInfo.settingGetForCategory("cat" .. i) end,
|
||||||
setFunc = function() AchievementInfo.settingToogle("cat" .. i) end
|
setFunc = function() AchievementInfo.settingToogle("cat" .. i) end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -167,6 +189,18 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Function to retrieve settings for categories (default true)
|
||||||
|
function AchievementInfo.settingGetForCategory(id)
|
||||||
|
if AchievementInfo.savedVars[id] == nil then
|
||||||
|
AchievementInfo.savedVars[id] = true
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return AchievementInfo.savedVars[id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Function to toggle Checkbox values
|
-- Function to toggle Checkbox values
|
||||||
function AchievementInfo.settingToogle(id)
|
function AchievementInfo.settingToogle(id)
|
||||||
if AchievementInfo.savedVars[id] == false then
|
if AchievementInfo.savedVars[id] == false then
|
||||||
@ -178,6 +212,17 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Function to toggle Checkbox value for accountWideSettings
|
||||||
|
function AchievementInfo.toggleAccountWideSettings()
|
||||||
|
if AchievementInfo.useAccountWideSettings["enabled"] == false then
|
||||||
|
AchievementInfo.useAccountWideSettings["enabled"] = true
|
||||||
|
else
|
||||||
|
AchievementInfo.useAccountWideSettings["enabled"] = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Function to set settings
|
-- Function to set settings
|
||||||
function AchievementInfo.settingSet(id, value)
|
function AchievementInfo.settingSet(id, value)
|
||||||
AchievementInfo.savedVars[id] = value
|
AchievementInfo.savedVars[id] = value
|
||||||
|
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,5 +1,21 @@
|
|||||||
#### Notable Changes
|
#### Notable Changes
|
||||||
|
|
||||||
|
##### Release 4.15
|
||||||
|
* Fixed "bracket style" of the achievement links, thanks to DakJaniels
|
||||||
|
|
||||||
|
##### Release 4.5
|
||||||
|
* Fixed "ShowDetails" option working only in combination with "ShowOpenDetailsOnly"
|
||||||
|
|
||||||
|
##### Release 4.3
|
||||||
|
* Fixed an error with gendered achievement descriptions
|
||||||
|
|
||||||
|
##### Release 4.0
|
||||||
|
* Added accountwide settings
|
||||||
|
* Added an "use accountwide settings" option to the settings of each character
|
||||||
|
|
||||||
|
##### Release 3.0
|
||||||
|
* Removed the bundled Dependency LibAddonMenu-2.0: You have to download it on your own now
|
||||||
|
|
||||||
##### Release 2.24
|
##### Release 2.24
|
||||||
* Updated Dependencies
|
* Updated Dependencies
|
||||||
* Removed LibStub Usage
|
* Removed LibStub Usage
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
## APIVersion: 100029 100030
|
|
||||||
## Title: LibAddonMenu-2.0
|
|
||||||
## Version: 2.0 r30
|
|
||||||
## AddOnVersion: 30
|
|
||||||
## IsLibrary: true
|
|
||||||
## OptionalDependsOn: LibStub LibDebugLogger
|
|
||||||
## Author: Seerah, sirinsidiator, et al.
|
|
||||||
## Contributors: votan, merlight, Garkin, Randactyl, KuroiLight, silvereyes333, Baertram, kyoma, klingo, phuein
|
|
||||||
## 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.
|
|
||||||
## The Elder Scrolls® and related logos are registered trademarks or trademarks of ZeniMax Media Inc. in the United States and/or other countries.
|
|
||||||
## All rights reserved
|
|
||||||
##
|
|
||||||
## You can read the full terms at https://account.elderscrollsonline.com/add-on-terms
|
|
||||||
|
|
||||||
LibStub\LibStub.lua
|
|
||||||
|
|
||||||
LibAddonMenu-2.0\LibAddonMenu-2.0.lua
|
|
||||||
|
|
||||||
LibAddonMenu-2.0\controls\panel.lua
|
|
||||||
LibAddonMenu-2.0\controls\submenu.lua
|
|
||||||
LibAddonMenu-2.0\controls\button.lua
|
|
||||||
LibAddonMenu-2.0\controls\checkbox.lua
|
|
||||||
LibAddonMenu-2.0\controls\colorpicker.lua
|
|
||||||
LibAddonMenu-2.0\controls\custom.lua
|
|
||||||
LibAddonMenu-2.0\controls\description.lua
|
|
||||||
LibAddonMenu-2.0\controls\dropdown.lua
|
|
||||||
LibAddonMenu-2.0\controls\editbox.lua
|
|
||||||
LibAddonMenu-2.0\controls\header.lua
|
|
||||||
LibAddonMenu-2.0\controls\slider.lua
|
|
||||||
LibAddonMenu-2.0\controls\texture.lua
|
|
||||||
LibAddonMenu-2.0\controls\iconpicker.lua
|
|
||||||
LibAddonMenu-2.0\controls\divider.lua
|
|
@ -1,201 +0,0 @@
|
|||||||
The Artistic License 2.0
|
|
||||||
|
|
||||||
Copyright (c) 2016 Ryan Lakanen (Seerah)
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
This license establishes the terms under which a given free software
|
|
||||||
Package may be copied, modified, distributed, and/or redistributed.
|
|
||||||
The intent is that the Copyright Holder maintains some artistic
|
|
||||||
control over the development of that Package while still keeping the
|
|
||||||
Package available as open source and free software.
|
|
||||||
|
|
||||||
You are always permitted to make arrangements wholly outside of this
|
|
||||||
license directly with the Copyright Holder of a given Package. If the
|
|
||||||
terms of this license do not permit the full use that you propose to
|
|
||||||
make of the Package, you should contact the Copyright Holder and seek
|
|
||||||
a different licensing arrangement.
|
|
||||||
|
|
||||||
Definitions
|
|
||||||
|
|
||||||
"Copyright Holder" means the individual(s) or organization(s)
|
|
||||||
named in the copyright notice for the entire Package.
|
|
||||||
|
|
||||||
"Contributor" means any party that has contributed code or other
|
|
||||||
material to the Package, in accordance with the Copyright Holder's
|
|
||||||
procedures.
|
|
||||||
|
|
||||||
"You" and "your" means any person who would like to copy,
|
|
||||||
distribute, or modify the Package.
|
|
||||||
|
|
||||||
"Package" means the collection of files distributed by the
|
|
||||||
Copyright Holder, and derivatives of that collection and/or of
|
|
||||||
those files. A given Package may consist of either the Standard
|
|
||||||
Version, or a Modified Version.
|
|
||||||
|
|
||||||
"Distribute" means providing a copy of the Package or making it
|
|
||||||
accessible to anyone else, or in the case of a company or
|
|
||||||
organization, to others outside of your company or organization.
|
|
||||||
|
|
||||||
"Distributor Fee" means any fee that you charge for Distributing
|
|
||||||
this Package or providing support for this Package to another
|
|
||||||
party. It does not mean licensing fees.
|
|
||||||
|
|
||||||
"Standard Version" refers to the Package if it has not been
|
|
||||||
modified, or has been modified only in ways explicitly requested
|
|
||||||
by the Copyright Holder.
|
|
||||||
|
|
||||||
"Modified Version" means the Package, if it has been changed, and
|
|
||||||
such changes were not explicitly requested by the Copyright
|
|
||||||
Holder.
|
|
||||||
|
|
||||||
"Original License" means this Artistic License as Distributed with
|
|
||||||
the Standard Version of the Package, in its current version or as
|
|
||||||
it may be modified by The Perl Foundation in the future.
|
|
||||||
|
|
||||||
"Source" form means the source code, documentation source, and
|
|
||||||
configuration files for the Package.
|
|
||||||
|
|
||||||
"Compiled" form means the compiled bytecode, object code, binary,
|
|
||||||
or any other form resulting from mechanical transformation or
|
|
||||||
translation of the Source form.
|
|
||||||
|
|
||||||
|
|
||||||
Permission for Use and Modification Without Distribution
|
|
||||||
|
|
||||||
(1) You are permitted to use the Standard Version and create and use
|
|
||||||
Modified Versions for any purpose without restriction, provided that
|
|
||||||
you do not Distribute the Modified Version.
|
|
||||||
|
|
||||||
|
|
||||||
Permissions for Redistribution of the Standard Version
|
|
||||||
|
|
||||||
(2) You may Distribute verbatim copies of the Source form of the
|
|
||||||
Standard Version of this Package in any medium without restriction,
|
|
||||||
either gratis or for a Distributor Fee, provided that you duplicate
|
|
||||||
all of the original copyright notices and associated disclaimers. At
|
|
||||||
your discretion, such verbatim copies may or may not include a
|
|
||||||
Compiled form of the Package.
|
|
||||||
|
|
||||||
(3) You may apply any bug fixes, portability changes, and other
|
|
||||||
modifications made available from the Copyright Holder. The resulting
|
|
||||||
Package will still be considered the Standard Version, and as such
|
|
||||||
will be subject to the Original License.
|
|
||||||
|
|
||||||
|
|
||||||
Distribution of Modified Versions of the Package as Source
|
|
||||||
|
|
||||||
(4) You may Distribute your Modified Version as Source (either gratis
|
|
||||||
or for a Distributor Fee, and with or without a Compiled form of the
|
|
||||||
Modified Version) provided that you clearly document how it differs
|
|
||||||
from the Standard Version, including, but not limited to, documenting
|
|
||||||
any non-standard features, executables, or modules, and provided that
|
|
||||||
you do at least ONE of the following:
|
|
||||||
|
|
||||||
(a) make the Modified Version available to the Copyright Holder
|
|
||||||
of the Standard Version, under the Original License, so that the
|
|
||||||
Copyright Holder may include your modifications in the Standard
|
|
||||||
Version.
|
|
||||||
|
|
||||||
(b) ensure that installation of your Modified Version does not
|
|
||||||
prevent the user installing or running the Standard Version. In
|
|
||||||
addition, the Modified Version must bear a name that is different
|
|
||||||
from the name of the Standard Version.
|
|
||||||
|
|
||||||
(c) allow anyone who receives a copy of the Modified Version to
|
|
||||||
make the Source form of the Modified Version available to others
|
|
||||||
under
|
|
||||||
|
|
||||||
(i) the Original License or
|
|
||||||
|
|
||||||
(ii) a license that permits the licensee to freely copy,
|
|
||||||
modify and redistribute the Modified Version using the same
|
|
||||||
licensing terms that apply to the copy that the licensee
|
|
||||||
received, and requires that the Source form of the Modified
|
|
||||||
Version, and of any works derived from it, be made freely
|
|
||||||
available in that license fees are prohibited but Distributor
|
|
||||||
Fees are allowed.
|
|
||||||
|
|
||||||
|
|
||||||
Distribution of Compiled Forms of the Standard Version
|
|
||||||
or Modified Versions without the Source
|
|
||||||
|
|
||||||
(5) You may Distribute Compiled forms of the Standard Version without
|
|
||||||
the Source, provided that you include complete instructions on how to
|
|
||||||
get the Source of the Standard Version. Such instructions must be
|
|
||||||
valid at the time of your distribution. If these instructions, at any
|
|
||||||
time while you are carrying out such distribution, become invalid, you
|
|
||||||
must provide new instructions on demand or cease further distribution.
|
|
||||||
If you provide valid instructions or cease distribution within thirty
|
|
||||||
days after you become aware that the instructions are invalid, then
|
|
||||||
you do not forfeit any of your rights under this license.
|
|
||||||
|
|
||||||
(6) You may Distribute a Modified Version in Compiled form without
|
|
||||||
the Source, provided that you comply with Section 4 with respect to
|
|
||||||
the Source of the Modified Version.
|
|
||||||
|
|
||||||
|
|
||||||
Aggregating or Linking the Package
|
|
||||||
|
|
||||||
(7) You may aggregate the Package (either the Standard Version or
|
|
||||||
Modified Version) with other packages and Distribute the resulting
|
|
||||||
aggregation provided that you do not charge a licensing fee for the
|
|
||||||
Package. Distributor Fees are permitted, and licensing fees for other
|
|
||||||
components in the aggregation are permitted. The terms of this license
|
|
||||||
apply to the use and Distribution of the Standard or Modified Versions
|
|
||||||
as included in the aggregation.
|
|
||||||
|
|
||||||
(8) You are permitted to link Modified and Standard Versions with
|
|
||||||
other works, to embed the Package in a larger work of your own, or to
|
|
||||||
build stand-alone binary or bytecode versions of applications that
|
|
||||||
include the Package, and Distribute the result without restriction,
|
|
||||||
provided the result does not expose a direct interface to the Package.
|
|
||||||
|
|
||||||
|
|
||||||
Items That are Not Considered Part of a Modified Version
|
|
||||||
|
|
||||||
(9) Works (including, but not limited to, modules and scripts) that
|
|
||||||
merely extend or make use of the Package, do not, by themselves, cause
|
|
||||||
the Package to be a Modified Version. In addition, such works are not
|
|
||||||
considered parts of the Package itself, and are not subject to the
|
|
||||||
terms of this license.
|
|
||||||
|
|
||||||
|
|
||||||
General Provisions
|
|
||||||
|
|
||||||
(10) Any use, modification, and distribution of the Standard or
|
|
||||||
Modified Versions is governed by this Artistic License. By using,
|
|
||||||
modifying or distributing the Package, you accept this license. Do not
|
|
||||||
use, modify, or distribute the Package, if you do not accept this
|
|
||||||
license.
|
|
||||||
|
|
||||||
(11) If your Modified Version has been derived from a Modified
|
|
||||||
Version made by someone other than you, you are nevertheless required
|
|
||||||
to ensure that your Modified Version complies with the requirements of
|
|
||||||
this license.
|
|
||||||
|
|
||||||
(12) This license does not grant you the right to use any trademark,
|
|
||||||
service mark, tradename, or logo of the Copyright Holder.
|
|
||||||
|
|
||||||
(13) This license includes the non-exclusive, worldwide,
|
|
||||||
free-of-charge patent license to make, have made, use, offer to sell,
|
|
||||||
sell, import and otherwise transfer the Package with respect to any
|
|
||||||
patent claims licensable by the Copyright Holder that are necessarily
|
|
||||||
infringed by the Package. If you institute patent litigation
|
|
||||||
(including a cross-claim or counterclaim) against any party alleging
|
|
||||||
that the Package constitutes direct or contributory patent
|
|
||||||
infringement, then this Artistic License to you shall terminate on the
|
|
||||||
date that such litigation is filed.
|
|
||||||
|
|
||||||
(14) Disclaimer of Warranty:
|
|
||||||
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
|
|
||||||
IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
|
|
||||||
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
|
|
||||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
|
|
||||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,91 +0,0 @@
|
|||||||
--[[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)
|
|
||||||
reference = "MyAddonButton", -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
local widgetVersion = 11
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("button", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable = control.data.disabled
|
|
||||||
if type(disable) == "function" then
|
|
||||||
disable = disable()
|
|
||||||
end
|
|
||||||
control.button:SetEnabled(not disable)
|
|
||||||
end
|
|
||||||
|
|
||||||
--controlName is optional
|
|
||||||
local MIN_HEIGHT = 28 -- default_button height
|
|
||||||
local HALF_WIDTH_LINE_SPACING = 2
|
|
||||||
function LAMCreateControl.button(parent, buttonData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, buttonData, controlName)
|
|
||||||
control:SetMouseEnabled(true)
|
|
||||||
|
|
||||||
local width = control:GetWidth()
|
|
||||||
if control.isHalfWidth then
|
|
||||||
control:SetDimensions(width / 2, MIN_HEIGHT * 2 + HALF_WIDTH_LINE_SPACING)
|
|
||||||
else
|
|
||||||
control:SetDimensions(width, MIN_HEIGHT)
|
|
||||||
end
|
|
||||||
|
|
||||||
if buttonData.icon then
|
|
||||||
control.button = wm:CreateControl(nil, control, CT_BUTTON)
|
|
||||||
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:SetWidth(width / 3)
|
|
||||||
control.button:SetText(LAM.util.GetStringFromValue(buttonData.name))
|
|
||||||
if buttonData.isDangerous then control.button:SetNormalFontColor(ZO_ERROR_COLOR:UnpackRGBA()) end
|
|
||||||
end
|
|
||||||
local button = control.button
|
|
||||||
button:SetAnchor(control.isHalfWidth and CENTER or RIGHT)
|
|
||||||
button:SetClickSound("Click")
|
|
||||||
button.data = {tooltipText = LAM.util.GetStringFromValue(buttonData.tooltip)}
|
|
||||||
button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
|
|
||||||
button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
|
|
||||||
button:SetHandler("OnClicked", function(...)
|
|
||||||
local args = {...}
|
|
||||||
local function callback()
|
|
||||||
buttonData.func(unpack(args))
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
end
|
|
||||||
|
|
||||||
if(buttonData.isDangerous) then
|
|
||||||
local title = LAM.util.GetStringFromValue(buttonData.name)
|
|
||||||
local body = LAM.util.GetStringFromValue(buttonData.warning)
|
|
||||||
LAM.util.ShowConfirmationDialog(title, body, callback)
|
|
||||||
else
|
|
||||||
callback()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if buttonData.warning ~= nil then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
if buttonData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,142 +0,0 @@
|
|||||||
--[[checkboxData = {
|
|
||||||
type = "checkbox",
|
|
||||||
name = "My Checkbox", -- or string id or function returning a string
|
|
||||||
getFunc = function() return db.var end,
|
|
||||||
setFunc = function(value) db.var = value doStuff() end,
|
|
||||||
tooltip = "Checkbox's tooltip text.", -- or string id or function returning a string (optional)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
disabled = function() return db.someBooleanSetting end, -- or boolean (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)
|
|
||||||
default = defaults.var, -- a boolean or function that returns a boolean (optional)
|
|
||||||
reference = "MyAddonCheckbox", -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 14
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("checkbox", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
--label
|
|
||||||
local enabledColor = ZO_DEFAULT_ENABLED_COLOR
|
|
||||||
local enabledHLcolor = ZO_HIGHLIGHT_TEXT
|
|
||||||
local disabledColor = ZO_DEFAULT_DISABLED_COLOR
|
|
||||||
local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR
|
|
||||||
--checkbox
|
|
||||||
local checkboxColor = ZO_NORMAL_TEXT
|
|
||||||
local checkboxHLcolor = ZO_HIGHLIGHT_TEXT
|
|
||||||
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
disable = control.data.disabled()
|
|
||||||
else
|
|
||||||
disable = control.data.disabled
|
|
||||||
end
|
|
||||||
|
|
||||||
control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA())
|
|
||||||
control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA())
|
|
||||||
--control:SetMouseEnabled(not disable)
|
|
||||||
--control:SetMouseEnabled(true)
|
|
||||||
|
|
||||||
control.isDisabled = disable
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ToggleCheckbox(control)
|
|
||||||
if control.value then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
control.checkbox:SetText(control.checkedText)
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
control.checkbox:SetText(control.uncheckedText)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, value)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
value = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
control.data.setFunc(value)
|
|
||||||
elseif value ~= nil then --our value could be false
|
|
||||||
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
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
value = control.data.getFunc()
|
|
||||||
end
|
|
||||||
control.value = value
|
|
||||||
|
|
||||||
ToggleCheckbox(control)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function OnMouseEnter(control)
|
|
||||||
ZO_Options_OnMouseEnter(control)
|
|
||||||
|
|
||||||
if control.isDisabled then return end
|
|
||||||
|
|
||||||
local label = control.label
|
|
||||||
if control.value then
|
|
||||||
label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
|
|
||||||
else
|
|
||||||
label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
|
|
||||||
end
|
|
||||||
|
|
||||||
local function OnMouseExit(control)
|
|
||||||
ZO_Options_OnMouseExit(control)
|
|
||||||
|
|
||||||
if control.isDisabled then return end
|
|
||||||
|
|
||||||
local label = control.label
|
|
||||||
if control.value then
|
|
||||||
label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
|
|
||||||
end
|
|
||||||
|
|
||||||
--controlName is optional
|
|
||||||
function LAMCreateControl.checkbox(parent, checkboxData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, checkboxData, controlName)
|
|
||||||
control:SetHandler("OnMouseEnter", OnMouseEnter)
|
|
||||||
control:SetHandler("OnMouseExit", OnMouseExit)
|
|
||||||
control:SetHandler("OnMouseUp", function(control)
|
|
||||||
if control.isDisabled then return end
|
|
||||||
PlaySound(SOUNDS.DEFAULT_CLICK)
|
|
||||||
control.value = not control.value
|
|
||||||
control:UpdateValue(false, control.value)
|
|
||||||
end)
|
|
||||||
|
|
||||||
control.checkbox = wm:CreateControl(nil, control.container, CT_LABEL)
|
|
||||||
local checkbox = control.checkbox
|
|
||||||
checkbox:SetAnchor(LEFT, control.container, LEFT, 0, 0)
|
|
||||||
checkbox:SetFont("ZoFontGameBold")
|
|
||||||
checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
|
|
||||||
control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper()
|
|
||||||
control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper()
|
|
||||||
|
|
||||||
if checkboxData.warning ~= nil or checkboxData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.data.tooltipText = LAM.util.GetStringFromValue(checkboxData.tooltip)
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
if checkboxData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,110 +0,0 @@
|
|||||||
--[[colorpickerData = {
|
|
||||||
type = "colorpicker",
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
disabled = function() return db.someBooleanSetting end, -- or boolean (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)
|
|
||||||
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)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 14
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
disable = control.data.disabled()
|
|
||||||
else
|
|
||||||
disable = control.data.disabled
|
|
||||||
end
|
|
||||||
|
|
||||||
if disable then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
|
|
||||||
control.isDisabled = disable
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
local color = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a
|
|
||||||
control.data.setFunc(valueR, valueG, valueB, valueA)
|
|
||||||
elseif valueR and valueG and valueB then
|
|
||||||
control.data.setFunc(valueR, valueG, valueB, valueA or 1)
|
|
||||||
--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
valueR, valueG, valueB, valueA = control.data.getFunc()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.thumb:SetColor(valueR, valueG, valueB, valueA or 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, colorpickerData, controlName)
|
|
||||||
|
|
||||||
control.color = control.container
|
|
||||||
local color = control.color
|
|
||||||
|
|
||||||
control.thumb = wm:CreateControl(nil, color, CT_TEXTURE)
|
|
||||||
local thumb = control.thumb
|
|
||||||
thumb:SetDimensions(36, 18)
|
|
||||||
thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
|
|
||||||
|
|
||||||
color.border = wm:CreateControl(nil, color, CT_TEXTURE)
|
|
||||||
local border = color.border
|
|
||||||
border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds")
|
|
||||||
border:SetTextureCoords(0, .625, 0, .8125)
|
|
||||||
border:SetDimensions(40, 22)
|
|
||||||
border:SetAnchor(CENTER, thumb, CENTER, 0, 0)
|
|
||||||
|
|
||||||
local function ColorPickerCallback(r, g, b, a)
|
|
||||||
control:UpdateValue(false, r, g, b, a)
|
|
||||||
end
|
|
||||||
|
|
||||||
control:SetHandler("OnMouseUp", function(self, btn, upInside)
|
|
||||||
if self.isDisabled then return end
|
|
||||||
|
|
||||||
if upInside then
|
|
||||||
local r, g, b, a = colorpickerData.getFunc()
|
|
||||||
if IsInGamepadPreferredMode() then
|
|
||||||
COLOR_PICKER_GAMEPAD:Show(ColorPickerCallback, r, g, b, a)
|
|
||||||
else
|
|
||||||
COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if colorpickerData.warning ~= nil or colorpickerData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.data.tooltipText = LAM.util.GetStringFromValue(colorpickerData.tooltip)
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
if colorpickerData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,35 +0,0 @@
|
|||||||
--[[customData = {
|
|
||||||
type = "custom",
|
|
||||||
reference = "MyAddonCustomControl", -- unique name for your control to use as reference (optional)
|
|
||||||
refreshFunc = function(customControl) end, -- function to call when panel/controls refresh (optional)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
local widgetVersion = 7
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("custom", widgetVersion) then return end
|
|
||||||
|
|
||||||
local function UpdateValue(control)
|
|
||||||
if control.data.refreshFunc then
|
|
||||||
control.data.refreshFunc(control)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 26
|
|
||||||
function LAMCreateControl.custom(parent, customData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, customData, controlName)
|
|
||||||
local width = control:GetWidth()
|
|
||||||
control:SetResizeToFitDescendents(true)
|
|
||||||
|
|
||||||
if control.isHalfWidth then --note these restrictions
|
|
||||||
control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
|
|
||||||
else
|
|
||||||
control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
|
|
||||||
end
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,96 +0,0 @@
|
|||||||
--[[descriptionData = {
|
|
||||||
type = "description",
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 10
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("description", widgetVersion) then return end
|
|
||||||
|
|
||||||
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)
|
|
||||||
if control.title then
|
|
||||||
control.title:SetText(LAM.util.GetStringFromValue(control.data.title))
|
|
||||||
end
|
|
||||||
control.desc:SetText(LAM.util.GetStringFromValue(control.data.text))
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.description(parent, descriptionData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, descriptionData, controlName)
|
|
||||||
local isHalfWidth = control.isHalfWidth
|
|
||||||
local width = control:GetWidth()
|
|
||||||
control:SetResizeToFitDescendents(true)
|
|
||||||
|
|
||||||
if isHalfWidth then
|
|
||||||
control:SetDimensionConstraints(width / 2, 0, width / 2, 0)
|
|
||||||
else
|
|
||||||
control:SetDimensionConstraints(width, 0, width, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
control.desc = wm:CreateControl(nil, control, CT_LABEL)
|
|
||||||
local desc = control.desc
|
|
||||||
desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
|
|
||||||
desc:SetFont("ZoFontGame")
|
|
||||||
desc:SetText(LAM.util.GetStringFromValue(descriptionData.text))
|
|
||||||
desc:SetWidth(isHalfWidth and width / 2 or width)
|
|
||||||
|
|
||||||
if descriptionData.title then
|
|
||||||
control.title = wm:CreateControl(nil, control, CT_LABEL)
|
|
||||||
local title = control.title
|
|
||||||
title:SetWidth(isHalfWidth and width / 2 or width)
|
|
||||||
title:SetAnchor(TOPLEFT, control, TOPLEFT)
|
|
||||||
title:SetFont("ZoFontWinH4")
|
|
||||||
title:SetText(LAM.util.GetStringFromValue(descriptionData.title))
|
|
||||||
desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT)
|
|
||||||
else
|
|
||||||
desc:SetAnchor(TOPLEFT)
|
|
||||||
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
|
|
||||||
if descriptionData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
|
|
||||||
end
|
|
@ -1,45 +0,0 @@
|
|||||||
--[[dividerData = {
|
|
||||||
type = "divider",
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
height = 10, -- (optional)
|
|
||||||
alpha = 0.25, -- (optional)
|
|
||||||
reference = "MyAddonDivider" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 2
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("divider", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 10
|
|
||||||
local MAX_HEIGHT = 50
|
|
||||||
local MIN_ALPHA = 0
|
|
||||||
local MAX_ALPHA = 1
|
|
||||||
local DEFAULT_ALPHA = 0.25
|
|
||||||
|
|
||||||
local function GetValueInRange(value, min, max, default)
|
|
||||||
if not value or type(value) ~= "number" then
|
|
||||||
return default
|
|
||||||
end
|
|
||||||
return math.min(math.max(min, value), max)
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.divider(parent, dividerData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, dividerData, controlName)
|
|
||||||
local isHalfWidth = control.isHalfWidth
|
|
||||||
local width = control:GetWidth()
|
|
||||||
local height = GetValueInRange(dividerData.height, MIN_HEIGHT, MAX_HEIGHT, MIN_HEIGHT)
|
|
||||||
local alpha = GetValueInRange(dividerData.alpha, MIN_ALPHA, MAX_ALPHA, DEFAULT_ALPHA)
|
|
||||||
|
|
||||||
control:SetDimensions(isHalfWidth and width / 2 or width, height)
|
|
||||||
|
|
||||||
control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
|
|
||||||
local divider = control.divider
|
|
||||||
divider:SetWidth(isHalfWidth and width / 2 or width)
|
|
||||||
divider:SetAnchor(TOPLEFT)
|
|
||||||
divider:SetAlpha(alpha)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,432 +0,0 @@
|
|||||||
--[[dropdownData = {
|
|
||||||
type = "dropdown",
|
|
||||||
name = "My Dropdown", -- or string id or function returning a string
|
|
||||||
choices = {"table", "of", "choices"},
|
|
||||||
choicesValues = {"foo", 2, "three"}, -- if specified, these values will get passed to setFunc instead (optional)
|
|
||||||
getFunc = function() return db.var end,
|
|
||||||
setFunc = function(var) db.var = var doStuff() end,
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
default = defaults.var, -- default value or function that returns the default value (optional)
|
|
||||||
reference = "MyAddonDropdown" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 20
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
local cm = CALLBACK_MANAGER
|
|
||||||
local SORT_BY_VALUE = { ["value"] = {} }
|
|
||||||
local SORT_BY_VALUE_NUMERIC = { ["value"] = { isNumeric = true } }
|
|
||||||
local SORT_TYPES = {
|
|
||||||
name = ZO_SORT_BY_NAME,
|
|
||||||
numeric = ZO_SORT_BY_NAME_NUMERIC,
|
|
||||||
value = SORT_BY_VALUE,
|
|
||||||
numericvalue = SORT_BY_VALUE_NUMERIC,
|
|
||||||
}
|
|
||||||
local SORT_ORDERS = {
|
|
||||||
up = ZO_SORT_ORDER_UP,
|
|
||||||
down = ZO_SORT_ORDER_DOWN,
|
|
||||||
}
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
disable = control.data.disabled()
|
|
||||||
else
|
|
||||||
disable = control.data.disabled
|
|
||||||
end
|
|
||||||
|
|
||||||
control.dropdown:SetEnabled(not disable)
|
|
||||||
if disable then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, value)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
value = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
control.data.setFunc(value)
|
|
||||||
control.dropdown:SetSelectedItem(control.choices[value])
|
|
||||||
elseif value then
|
|
||||||
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
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
value = control.data.getFunc()
|
|
||||||
control.dropdown:SetSelectedItem(control.choices[value])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function DropdownCallback(control, choiceText, choice)
|
|
||||||
choice.control:UpdateValue(false, choice.value or choiceText)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function SetupTooltips(comboBox, choicesTooltips)
|
|
||||||
local function ShowTooltip(control)
|
|
||||||
InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
|
|
||||||
SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.tooltip))
|
|
||||||
InformationTooltipTopLevel:BringWindowToTop()
|
|
||||||
end
|
|
||||||
local function HideTooltip(control)
|
|
||||||
ClearTooltip(InformationTooltip)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- allow for tooltips on the drop down entries
|
|
||||||
local originalShow = comboBox.ShowDropdownInternal
|
|
||||||
comboBox.ShowDropdownInternal = function(comboBox)
|
|
||||||
originalShow(comboBox)
|
|
||||||
local entries = ZO_Menu.items
|
|
||||||
for i = 1, #entries do
|
|
||||||
local entry = entries[i]
|
|
||||||
local control = entries[i].item
|
|
||||||
control.tooltip = choicesTooltips[i]
|
|
||||||
entry.onMouseEnter = control:GetHandler("OnMouseEnter")
|
|
||||||
entry.onMouseExit = control:GetHandler("OnMouseExit")
|
|
||||||
ZO_PreHookHandler(control, "OnMouseEnter", ShowTooltip)
|
|
||||||
ZO_PreHookHandler(control, "OnMouseExit", HideTooltip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local originalHide = comboBox.HideDropdownInternal
|
|
||||||
comboBox.HideDropdownInternal = function(self)
|
|
||||||
local entries = ZO_Menu.items
|
|
||||||
for i = 1, #entries do
|
|
||||||
local entry = entries[i]
|
|
||||||
local control = entries[i].item
|
|
||||||
control:SetHandler("OnMouseEnter", entry.onMouseEnter)
|
|
||||||
control:SetHandler("OnMouseExit", entry.onMouseExit)
|
|
||||||
control.tooltip = nil
|
|
||||||
end
|
|
||||||
originalHide(self)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateChoices(control, choices, choicesValues, choicesTooltips)
|
|
||||||
control.dropdown:ClearItems() --remove previous choices --(need to call :SetSelectedItem()?)
|
|
||||||
ZO_ClearTable(control.choices)
|
|
||||||
|
|
||||||
--build new list of choices
|
|
||||||
local choices = choices or control.data.choices
|
|
||||||
local choicesValues = choicesValues or control.data.choicesValues
|
|
||||||
local choicesTooltips = choicesTooltips or control.data.choicesTooltips
|
|
||||||
|
|
||||||
if choicesValues then
|
|
||||||
assert(#choices == #choicesValues, "choices and choicesValues need to have the same size")
|
|
||||||
end
|
|
||||||
|
|
||||||
if choicesTooltips then
|
|
||||||
assert(#choices == #choicesTooltips, "choices and choicesTooltips need to have the same size")
|
|
||||||
if not control.scrollHelper then -- only do this for non-scrollable
|
|
||||||
SetupTooltips(control.dropdown, choicesTooltips)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, #choices do
|
|
||||||
local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback)
|
|
||||||
entry.control = control
|
|
||||||
if choicesValues then
|
|
||||||
entry.value = choicesValues[i]
|
|
||||||
end
|
|
||||||
if choicesTooltips and control.scrollHelper then
|
|
||||||
entry.tooltip = choicesTooltips[i]
|
|
||||||
end
|
|
||||||
control.choices[entry.value or entry.name] = entry.name
|
|
||||||
control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE) --if sort type/order isn't specified, then don't sort
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function GrabSortingInfo(sortInfo)
|
|
||||||
local t, i = {}, 1
|
|
||||||
for info in string.gmatch(sortInfo, "([^%-]+)") do
|
|
||||||
t[i] = info
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
|
|
||||||
local ENTRY_ID = 1
|
|
||||||
local LAST_ENTRY_ID = 2
|
|
||||||
local OFFSET_X_INDEX = 4
|
|
||||||
local DEFAULT_VISIBLE_ROWS = 10
|
|
||||||
local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = ZO_SCROLLABLE_ENTRY_TEMPLATE_HEIGHT
|
|
||||||
local SCROLLBAR_PADDING = ZO_SCROLL_BAR_WIDTH
|
|
||||||
local PADDING_X = GetMenuPadding()
|
|
||||||
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 ScrollableDropdownHelper = ZO_Object:Subclass()
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:New(...)
|
|
||||||
local object = ZO_Object.New(self)
|
|
||||||
object:Initialize(...)
|
|
||||||
return object
|
|
||||||
end
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:Initialize(panel, control, visibleRows)
|
|
||||||
local combobox = control.combobox
|
|
||||||
local dropdown = control.dropdown
|
|
||||||
self.panel = panel
|
|
||||||
self.control = control
|
|
||||||
self.combobox = combobox
|
|
||||||
self.dropdown = dropdown
|
|
||||||
self.visibleRows = visibleRows
|
|
||||||
|
|
||||||
-- clear anchors so we can adjust the width dynamically
|
|
||||||
dropdown.m_dropdown:ClearAnchors()
|
|
||||||
dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT)
|
|
||||||
|
|
||||||
-- handle dropdown or settingsmenu opening/closing
|
|
||||||
local function onShow() return self:OnShow() end
|
|
||||||
local function onHide() self:OnHide() end
|
|
||||||
local function doHide(closedPanel)
|
|
||||||
if closedPanel == panel then self:DoHide() end
|
|
||||||
end
|
|
||||||
|
|
||||||
ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow)
|
|
||||||
ZO_PreHook(dropdown, "HideDropdownInternal", onHide)
|
|
||||||
combobox:SetHandler("OnEffectivelyHidden", onHide)
|
|
||||||
cm:RegisterCallback("LAM-PanelClosed", doHide)
|
|
||||||
|
|
||||||
-- dont fade entries near the edges
|
|
||||||
local scrollList = dropdown.m_scroll
|
|
||||||
scrollList.selectionTemplate = nil
|
|
||||||
scrollList.highlightTemplate = nil
|
|
||||||
ZO_ScrollList_EnableSelection(scrollList, "ZO_SelectionHighlight")
|
|
||||||
ZO_ScrollList_EnableHighlight(scrollList, "ZO_SelectionHighlight")
|
|
||||||
ZO_Scroll_SetUseFadeGradient(scrollList, false)
|
|
||||||
|
|
||||||
-- adjust scroll content anchor to mimic menu padding
|
|
||||||
local scroll = dropdown.m_dropdown:GetNamedChild("Scroll")
|
|
||||||
local anchor1 = {select(2, scroll:GetAnchor(0))}
|
|
||||||
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:SetAnchor(unpack(anchor1))
|
|
||||||
scroll:SetAnchor(unpack(anchor2))
|
|
||||||
ZO_ScrollList_Commit(scrollList)
|
|
||||||
|
|
||||||
-- hook mouse enter/exit
|
|
||||||
local function onMouseEnter(control) self:OnMouseEnter(control) end
|
|
||||||
local function onMouseExit(control) self:OnMouseExit(control) end
|
|
||||||
|
|
||||||
-- adjust row setup to mimic the highlight padding
|
|
||||||
local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, ENTRY_ID)
|
|
||||||
local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, LAST_ENTRY_ID)
|
|
||||||
local oSetup = dataType1.setupCallback -- both types have the same setup function
|
|
||||||
local function SetupEntry(control, data, list)
|
|
||||||
oSetup(control, data, list)
|
|
||||||
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
|
|
||||||
if not control.hookedMouseHandlers then --only do it once per control
|
|
||||||
control.hookedMouseHandlers = true
|
|
||||||
ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter)
|
|
||||||
ZO_PreHookHandler(control, "OnMouseExit", onMouseExit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dataType1.setupCallback = SetupEntry
|
|
||||||
dataType2.setupCallback = SetupEntry
|
|
||||||
|
|
||||||
-- adjust dimensions based on entries
|
|
||||||
local scrollContent = scroll:GetNamedChild("Contents")
|
|
||||||
dropdown.AddMenuItems = ScrollableDropdownHelper.AddMenuItems
|
|
||||||
|
|
||||||
dropdown.AdjustDimensions = function()
|
|
||||||
local numItems = #dropdown.m_sortedItems
|
|
||||||
local contentWidth = self:CalculateContentWidth() + CONTENT_PADDING
|
|
||||||
local anchorOffset = 0
|
|
||||||
if(numItems > self.visibleRows) then
|
|
||||||
numItems = self.visibleRows
|
|
||||||
contentWidth = contentWidth + SCROLLBAR_PADDING
|
|
||||||
anchorOffset = -SCROLLBAR_PADDING
|
|
||||||
end
|
|
||||||
|
|
||||||
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:SetHeight(height)
|
|
||||||
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
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:OnShow()
|
|
||||||
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
|
|
||||||
dropdown.m_lastParent = dropdown.m_dropdown:GetParent()
|
|
||||||
dropdown.m_dropdown:SetParent(ZO_Menus)
|
|
||||||
ZO_Menus:BringWindowToTop()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:OnHide()
|
|
||||||
local dropdown = self.dropdown
|
|
||||||
if dropdown.m_lastParent then
|
|
||||||
dropdown.m_dropdown:SetParent(dropdown.m_lastParent)
|
|
||||||
dropdown.m_lastParent = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:DoHide()
|
|
||||||
local dropdown = self.dropdown
|
|
||||||
if dropdown:IsDropdownVisible() then
|
|
||||||
dropdown:HideDropdown()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:CalculateContentWidth()
|
|
||||||
local dropdown = self.dropdown
|
|
||||||
local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
|
|
||||||
|
|
||||||
local dummy = dataType.pool:AcquireObject()
|
|
||||||
dataType.setupCallback(dummy, {
|
|
||||||
m_owner = dropdown,
|
|
||||||
name = "Dummy"
|
|
||||||
}, dropdown)
|
|
||||||
|
|
||||||
local maxWidth = 0
|
|
||||||
local label = dummy.m_label
|
|
||||||
local entries = dropdown.m_sortedItems
|
|
||||||
local numItems = #entries
|
|
||||||
for index = 1, numItems do
|
|
||||||
label:SetText(entries[index].name)
|
|
||||||
local width = label:GetTextWidth()
|
|
||||||
if (width > maxWidth) then
|
|
||||||
maxWidth = width
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
dataType.pool:ReleaseObject(dummy.key)
|
|
||||||
return maxWidth
|
|
||||||
end
|
|
||||||
|
|
||||||
function ScrollableDropdownHelper:OnMouseEnter(control)
|
|
||||||
-- call original code if we replace instead of hook the handler
|
|
||||||
--ZO_ScrollableComboBox_Entry_OnMouseEnter(control)
|
|
||||||
-- show tooltip
|
|
||||||
if control.m_data.tooltip then
|
|
||||||
InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
|
|
||||||
SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.m_data.tooltip))
|
|
||||||
InformationTooltipTopLevel:BringWindowToTop()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ScrollableDropdownHelper:OnMouseExit(control)
|
|
||||||
-- call original code if we replace instead of hook the handler
|
|
||||||
--ZO_ScrollableComboBox_Entry_OnMouseExit(control)
|
|
||||||
-- hide tooltip
|
|
||||||
if control.m_data.tooltip then
|
|
||||||
ClearTooltip(InformationTooltip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.dropdown(parent, dropdownData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, dropdownData, controlName)
|
|
||||||
control.choices = {}
|
|
||||||
|
|
||||||
local countControl = parent
|
|
||||||
local name = parent:GetName()
|
|
||||||
if not name or #name == 0 then
|
|
||||||
countControl = LAMCreateControl
|
|
||||||
name = "LAM"
|
|
||||||
end
|
|
||||||
local comboboxCount = (countControl.comboboxCount or 0) + 1
|
|
||||||
countControl.comboboxCount = comboboxCount
|
|
||||||
control.combobox = wm:CreateControlFromVirtual(zo_strjoin(nil, name, "Combobox", comboboxCount), control.container, dropdownData.scrollable and "ZO_ScrollableComboBox" or "ZO_ComboBox")
|
|
||||||
|
|
||||||
local combobox = control.combobox
|
|
||||||
combobox:SetAnchor(TOPLEFT)
|
|
||||||
combobox:SetDimensions(control.container:GetDimensions())
|
|
||||||
combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
|
|
||||||
combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
|
|
||||||
control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox)
|
|
||||||
local dropdown = control.dropdown
|
|
||||||
dropdown:SetSortsItems(false) -- need to sort ourselves in order to be able to sort by value
|
|
||||||
|
|
||||||
if dropdownData.scrollable then
|
|
||||||
local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS
|
|
||||||
control.scrollHelper = ScrollableDropdownHelper:New(LAM.util.GetTopPanel(parent), control, visibleRows)
|
|
||||||
end
|
|
||||||
|
|
||||||
ZO_PreHook(dropdown, "UpdateItems", function(self)
|
|
||||||
assert(not self.m_sortsItems, "built-in dropdown sorting was reactivated, sorting is handled by LAM")
|
|
||||||
if control.m_sortOrder ~= nil and control.m_sortType then
|
|
||||||
local sortKey = next(control.m_sortType)
|
|
||||||
local sortFunc = function(item1, item2) return ZO_TableOrderingFunction(item1, item2, sortKey, control.m_sortType, control.m_sortOrder) end
|
|
||||||
table.sort(self.m_sortedItems, sortFunc)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if dropdownData.sort then
|
|
||||||
local sortInfo = GrabSortingInfo(dropdownData.sort)
|
|
||||||
control.m_sortType, control.m_sortOrder = SORT_TYPES[sortInfo[1]], SORT_ORDERS[sortInfo[2]]
|
|
||||||
elseif dropdownData.choicesValues then
|
|
||||||
control.m_sortType, control.m_sortOrder = ZO_SORT_ORDER_UP, SORT_BY_VALUE
|
|
||||||
end
|
|
||||||
|
|
||||||
if dropdownData.warning ~= nil or dropdownData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.UpdateChoices = UpdateChoices
|
|
||||||
control:UpdateChoices(dropdownData.choices, dropdownData.choicesValues)
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
if dropdownData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,156 +0,0 @@
|
|||||||
--[[editboxData = {
|
|
||||||
type = "editbox",
|
|
||||||
name = "My Editbox", -- or string id or function returning a string
|
|
||||||
getFunc = function() return db.text end,
|
|
||||||
setFunc = function(text) db.text = text doStuff() end,
|
|
||||||
tooltip = "Editbox's tooltip text.", -- or string id or function returning a string (optional)
|
|
||||||
isMultiline = true, -- boolean (optional)
|
|
||||||
isExtraWide = true, -- boolean (optional)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
disabled = function() return db.someBooleanSetting end, -- or boolean (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)
|
|
||||||
default = defaults.text, -- default value or function that returns the default value (optional)
|
|
||||||
reference = "MyAddonEditbox" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 14
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("editbox", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
disable = control.data.disabled()
|
|
||||||
else
|
|
||||||
disable = control.data.disabled
|
|
||||||
end
|
|
||||||
|
|
||||||
if disable then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
--control.editbox:SetEditEnabled(not disable)
|
|
||||||
control.editbox:SetMouseEnabled(not disable)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, value)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
value = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
control.data.setFunc(value)
|
|
||||||
control.editbox:SetText(value)
|
|
||||||
elseif value then
|
|
||||||
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
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
value = control.data.getFunc()
|
|
||||||
control.editbox:SetText(value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 24
|
|
||||||
local HALF_WIDTH_LINE_SPACING = 2
|
|
||||||
function LAMCreateControl.editbox(parent, editboxData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, editboxData, controlName)
|
|
||||||
|
|
||||||
local container = control.container
|
|
||||||
control.bg = wm:CreateControlFromVirtual(nil, container, "ZO_EditBackdrop")
|
|
||||||
local bg = control.bg
|
|
||||||
bg:SetAnchorFill()
|
|
||||||
|
|
||||||
if editboxData.isMultiline then
|
|
||||||
control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop")
|
|
||||||
control.editbox:SetHandler("OnMouseWheel", function(self, delta)
|
|
||||||
if self:HasFocus() then --only set focus to new spots if the editbox is currently in use
|
|
||||||
local cursorPos = self:GetCursorPosition()
|
|
||||||
local text = self:GetText()
|
|
||||||
local textLen = text:len()
|
|
||||||
local newPos
|
|
||||||
if delta > 0 then --scrolling up
|
|
||||||
local reverseText = text:reverse()
|
|
||||||
local revCursorPos = textLen - cursorPos
|
|
||||||
local revPos = reverseText:find("\n", revCursorPos+1)
|
|
||||||
newPos = revPos and textLen - revPos
|
|
||||||
else --scrolling down
|
|
||||||
newPos = text:find("\n", cursorPos+1)
|
|
||||||
end
|
|
||||||
if newPos then --if we found a new line, then scroll, otherwise don't
|
|
||||||
self:SetCursorPosition(newPos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop")
|
|
||||||
end
|
|
||||||
local editbox = control.editbox
|
|
||||||
editbox:SetText(editboxData.getFunc())
|
|
||||||
editbox:SetMaxInputChars(3000)
|
|
||||||
editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end)
|
|
||||||
editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end)
|
|
||||||
editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
|
|
||||||
editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
|
|
||||||
|
|
||||||
local MIN_WIDTH = (parent.GetWidth and (parent:GetWidth() / 10)) or (parent.panel.GetWidth and (parent.panel:GetWidth() / 10)) or 0
|
|
||||||
|
|
||||||
control.label:ClearAnchors()
|
|
||||||
container:ClearAnchors()
|
|
||||||
|
|
||||||
control.label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
|
|
||||||
container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
|
|
||||||
|
|
||||||
if control.isHalfWidth then
|
|
||||||
container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
if editboxData.isExtraWide then
|
|
||||||
container:SetAnchor(BOTTOMLEFT, control, BOTTOMLEFT, 0, 0)
|
|
||||||
else
|
|
||||||
container:SetWidth(MIN_WIDTH * 3.2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if editboxData.isMultiline then
|
|
||||||
container:SetHeight(MIN_HEIGHT * 3)
|
|
||||||
else
|
|
||||||
container:SetHeight(MIN_HEIGHT)
|
|
||||||
end
|
|
||||||
|
|
||||||
if control.isHalfWidth ~= true and editboxData.isExtraWide ~= true then
|
|
||||||
control:SetHeight(container:GetHeight())
|
|
||||||
else
|
|
||||||
control:SetHeight(container:GetHeight() + control.label:GetHeight())
|
|
||||||
end
|
|
||||||
|
|
||||||
editbox:ClearAnchors()
|
|
||||||
editbox:SetAnchor(TOPLEFT, container, TOPLEFT, 2, 2)
|
|
||||||
editbox:SetAnchor(BOTTOMRIGHT, container, BOTTOMRIGHT, -2, -2)
|
|
||||||
|
|
||||||
if editboxData.warning ~= nil or editboxData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
if editboxData.isExtraWide then
|
|
||||||
control.warning:SetAnchor(BOTTOMRIGHT, control.bg, TOPRIGHT, 2, 0)
|
|
||||||
else
|
|
||||||
control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0)
|
|
||||||
end
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
if editboxData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,42 +0,0 @@
|
|||||||
--[[headerData = {
|
|
||||||
type = "header",
|
|
||||||
name = "My Header", -- or string id or function returning a string
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
reference = "MyAddonHeader" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 8
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("header", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local function UpdateValue(control)
|
|
||||||
control.header:SetText(LAM.util.GetStringFromValue(control.data.name))
|
|
||||||
end
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 30
|
|
||||||
function LAMCreateControl.header(parent, headerData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, headerData, controlName)
|
|
||||||
local isHalfWidth = control.isHalfWidth
|
|
||||||
local width = control:GetWidth()
|
|
||||||
control:SetDimensions(isHalfWidth and width / 2 or width, MIN_HEIGHT)
|
|
||||||
|
|
||||||
control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
|
|
||||||
local divider = control.divider
|
|
||||||
divider:SetWidth(isHalfWidth and width / 2 or width)
|
|
||||||
divider:SetAnchor(TOPLEFT)
|
|
||||||
|
|
||||||
control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
|
|
||||||
local header = control.header
|
|
||||||
header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT)
|
|
||||||
header:SetAnchor(BOTTOMRIGHT)
|
|
||||||
header:SetText(LAM.util.GetStringFromValue(headerData.name))
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,436 +0,0 @@
|
|||||||
--[[iconpickerData = {
|
|
||||||
type = "iconpicker",
|
|
||||||
name = "My Icon Picker", -- or string id or function returning a string
|
|
||||||
choices = {"texture path 1", "texture path 2", "texture path 3"},
|
|
||||||
getFunc = function() return db.var end,
|
|
||||||
setFunc = function(var) db.var = var doStuff() end,
|
|
||||||
tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
|
|
||||||
choicesTooltips = {"icon tooltip 1", "icon tooltip 2", "icon tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
|
|
||||||
maxColumns = 5, -- number of icons in one row (optional)
|
|
||||||
visibleRows = 4.5, -- number of visible rows (optional)
|
|
||||||
iconSize = 28, -- size of the icons (optional)
|
|
||||||
defaultColor = ZO_ColorDef:New("FFFFFF"), -- default color of the icons (optional)
|
|
||||||
width = "full", --or "half" (optional)
|
|
||||||
beforeShow = function(control, iconPicker) return preventShow end, -- (optional)
|
|
||||||
disabled = function() return db.someBooleanSetting end, -- or boolean (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)
|
|
||||||
default = defaults.var, -- default value or function that returns the default value (optional)
|
|
||||||
reference = "MyAddonIconPicker" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
local widgetVersion = 8
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("iconpicker", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local IconPickerMenu = ZO_Object:Subclass()
|
|
||||||
local iconPicker
|
|
||||||
LAM.util.GetIconPickerMenu = function()
|
|
||||||
if not iconPicker then
|
|
||||||
iconPicker = IconPickerMenu:New("LAMIconPicker")
|
|
||||||
local sceneFragment = LAM:GetAddonSettingsFragment()
|
|
||||||
ZO_PreHook(sceneFragment, "OnHidden", function()
|
|
||||||
if not iconPicker.control:IsHidden() then
|
|
||||||
iconPicker:Clear()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
return iconPicker
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:New(...)
|
|
||||||
local object = ZO_Object.New(self)
|
|
||||||
object:Initialize(...)
|
|
||||||
return object
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:Initialize(name)
|
|
||||||
local control = wm:CreateTopLevelWindow(name)
|
|
||||||
control:SetDrawTier(DT_HIGH)
|
|
||||||
control:SetHidden(true)
|
|
||||||
self.control = control
|
|
||||||
|
|
||||||
local scrollContainer = wm:CreateControlFromVirtual(name .. "ScrollContainer", control, "ZO_ScrollContainer")
|
|
||||||
-- control:SetDimensions(control.container:GetWidth(), height) -- adjust to icon size / col count
|
|
||||||
scrollContainer:SetAnchorFill()
|
|
||||||
ZO_Scroll_SetUseFadeGradient(scrollContainer, false)
|
|
||||||
ZO_Scroll_SetHideScrollbarOnDisable(scrollContainer, false)
|
|
||||||
ZO_VerticalScrollbarBase_OnMouseExit(scrollContainer:GetNamedChild("ScrollBar")) -- scrollbar initialization seems to be broken so we force it to update the correct alpha value
|
|
||||||
local scroll = GetControl(scrollContainer, "ScrollChild")
|
|
||||||
self.scroll = scroll
|
|
||||||
self.scrollContainer = scrollContainer
|
|
||||||
|
|
||||||
local bg = wm:CreateControl(nil, scrollContainer, CT_BACKDROP)
|
|
||||||
bg:SetAnchor(TOPLEFT, scrollContainer, TOPLEFT, 0, -3)
|
|
||||||
bg:SetAnchor(BOTTOMRIGHT, scrollContainer, BOTTOMRIGHT, 2, 5)
|
|
||||||
bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
|
|
||||||
bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
|
|
||||||
bg:SetInsets(16, 16, -16, -16)
|
|
||||||
|
|
||||||
local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
|
|
||||||
mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
|
|
||||||
mungeOverlay:SetDrawLevel(1)
|
|
||||||
mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
|
|
||||||
mungeOverlay:SetAnchorFill()
|
|
||||||
|
|
||||||
local mouseOver = wm:CreateControl(nil, scrollContainer, CT_TEXTURE)
|
|
||||||
mouseOver:SetDrawLevel(2)
|
|
||||||
mouseOver:SetTexture("EsoUI/Art/Buttons/minmax_mouseover.dds")
|
|
||||||
mouseOver:SetHidden(true)
|
|
||||||
|
|
||||||
local function IconFactory(pool)
|
|
||||||
local icon = wm:CreateControl(name .. "Entry" .. pool:GetNextControlId(), scroll, CT_TEXTURE)
|
|
||||||
icon:SetMouseEnabled(true)
|
|
||||||
icon:SetDrawLevel(3)
|
|
||||||
icon:SetHandler("OnMouseEnter", function()
|
|
||||||
mouseOver:SetAnchor(TOPLEFT, icon, TOPLEFT, 0, 0)
|
|
||||||
mouseOver:SetAnchor(BOTTOMRIGHT, icon, BOTTOMRIGHT, 0, 0)
|
|
||||||
mouseOver:SetHidden(false)
|
|
||||||
if self.customOnMouseEnter then
|
|
||||||
self.customOnMouseEnter(icon)
|
|
||||||
else
|
|
||||||
self:OnMouseEnter(icon)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
icon:SetHandler("OnMouseExit", function()
|
|
||||||
mouseOver:ClearAnchors()
|
|
||||||
mouseOver:SetHidden(true)
|
|
||||||
if self.customOnMouseExit then
|
|
||||||
self.customOnMouseExit(icon)
|
|
||||||
else
|
|
||||||
self:OnMouseExit(icon)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
icon:SetHandler("OnMouseUp", function(control, ...)
|
|
||||||
PlaySound("Click")
|
|
||||||
icon.OnSelect(icon, icon.texture)
|
|
||||||
self:Clear()
|
|
||||||
end)
|
|
||||||
return icon
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ResetFunction(icon)
|
|
||||||
icon:ClearAnchors()
|
|
||||||
end
|
|
||||||
|
|
||||||
self.iconPool = ZO_ObjectPool:New(IconFactory, ResetFunction)
|
|
||||||
self:SetMaxColumns(1)
|
|
||||||
self.icons = {}
|
|
||||||
self.color = ZO_DEFAULT_ENABLED_COLOR
|
|
||||||
|
|
||||||
EVENT_MANAGER:RegisterForEvent(name .. "_OnGlobalMouseUp", EVENT_GLOBAL_MOUSE_UP, function()
|
|
||||||
if self.refCount ~= nil then
|
|
||||||
local moc = wm:GetMouseOverControl()
|
|
||||||
if(moc:GetOwningWindow() ~= control) then
|
|
||||||
self.refCount = self.refCount - 1
|
|
||||||
if self.refCount <= 0 then
|
|
||||||
self:Clear()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:OnMouseEnter(icon)
|
|
||||||
InitializeTooltip(InformationTooltip, icon, TOPLEFT, 0, 0, BOTTOMRIGHT)
|
|
||||||
SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(icon.tooltip))
|
|
||||||
InformationTooltipTopLevel:BringWindowToTop()
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:OnMouseExit(icon)
|
|
||||||
ClearTooltip(InformationTooltip)
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:SetMaxColumns(value)
|
|
||||||
self.maxCols = value ~= nil and value or 5
|
|
||||||
end
|
|
||||||
|
|
||||||
local DEFAULT_SIZE = 28
|
|
||||||
function IconPickerMenu:SetIconSize(value)
|
|
||||||
local iconSize = DEFAULT_SIZE
|
|
||||||
if value ~= nil then iconSize = math.max(iconSize, value) end
|
|
||||||
self.iconSize = iconSize
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:SetVisibleRows(value)
|
|
||||||
self.visibleRows = value ~= nil and value or 4.5
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:SetMouseHandlers(onEnter, onExit)
|
|
||||||
self.customOnMouseEnter = onEnter
|
|
||||||
self.customOnMouseExit = onExit
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:UpdateDimensions()
|
|
||||||
local iconSize = self.iconSize
|
|
||||||
local width = iconSize * self.maxCols + 20
|
|
||||||
local height = iconSize * self.visibleRows
|
|
||||||
self.control:SetDimensions(width, height)
|
|
||||||
|
|
||||||
local icons = self.icons
|
|
||||||
for i = 1, #icons do
|
|
||||||
local icon = icons[i]
|
|
||||||
icon:SetDimensions(iconSize, iconSize)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:UpdateAnchors()
|
|
||||||
local iconSize = self.iconSize
|
|
||||||
local col, maxCols = 1, self.maxCols
|
|
||||||
local previousCol, previousRow
|
|
||||||
local scroll = self.scroll
|
|
||||||
local icons = self.icons
|
|
||||||
|
|
||||||
for i = 1, #icons do
|
|
||||||
local icon = icons[i]
|
|
||||||
icon:ClearAnchors()
|
|
||||||
if i == 1 then
|
|
||||||
icon:SetAnchor(TOPLEFT, scroll, TOPLEFT, 0, 0)
|
|
||||||
previousRow = icon
|
|
||||||
elseif col == 1 then
|
|
||||||
icon:SetAnchor(TOPLEFT, previousRow, BOTTOMLEFT, 0, 0)
|
|
||||||
previousRow = icon
|
|
||||||
else
|
|
||||||
icon:SetAnchor(TOPLEFT, previousCol, TOPRIGHT, 0, 0)
|
|
||||||
end
|
|
||||||
previousCol = icon
|
|
||||||
col = col >= maxCols and 1 or col + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:Clear()
|
|
||||||
self.icons = {}
|
|
||||||
self.iconPool:ReleaseAllObjects()
|
|
||||||
self.control:SetHidden(true)
|
|
||||||
self.color = ZO_DEFAULT_ENABLED_COLOR
|
|
||||||
self.refCount = nil
|
|
||||||
self.parent = nil
|
|
||||||
self.customOnMouseEnter = nil
|
|
||||||
self.customOnMouseExit = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:AddIcon(texturePath, callback, tooltip)
|
|
||||||
local icon, key = self.iconPool:AcquireObject()
|
|
||||||
icon:SetTexture(texturePath)
|
|
||||||
icon:SetColor(self.color:UnpackRGBA())
|
|
||||||
icon.texture = texturePath
|
|
||||||
icon.tooltip = tooltip
|
|
||||||
icon.OnSelect = callback
|
|
||||||
self.icons[#self.icons + 1] = icon
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:Show(parent)
|
|
||||||
if #self.icons == 0 then return false end
|
|
||||||
if not self.control:IsHidden() then self:Clear() return false end
|
|
||||||
self:UpdateDimensions()
|
|
||||||
self:UpdateAnchors()
|
|
||||||
|
|
||||||
local control = self.control
|
|
||||||
control:ClearAnchors()
|
|
||||||
control:SetAnchor(TOPLEFT, parent, BOTTOMLEFT, 0, 8)
|
|
||||||
control:SetHidden(false)
|
|
||||||
control:BringWindowToTop()
|
|
||||||
self.parent = parent
|
|
||||||
self.refCount = 2
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function IconPickerMenu:SetColor(color)
|
|
||||||
local icons = self.icons
|
|
||||||
self.color = color
|
|
||||||
for i = 1, #icons do
|
|
||||||
local icon = icons[i]
|
|
||||||
icon:SetColor(color:UnpackRGBA())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
|
|
||||||
local function UpdateChoices(control, choices, choicesTooltips)
|
|
||||||
local data = control.data
|
|
||||||
if not choices then
|
|
||||||
choices, choicesTooltips = data.choices, data.choicesTooltips or {}
|
|
||||||
end
|
|
||||||
local addedChoices = {}
|
|
||||||
|
|
||||||
local iconPicker = LAM.util.GetIconPickerMenu()
|
|
||||||
iconPicker:Clear()
|
|
||||||
for i = 1, #choices do
|
|
||||||
local texture = choices[i]
|
|
||||||
if not addedChoices[texture] then -- remove duplicates
|
|
||||||
iconPicker:AddIcon(choices[i], function(self, texture)
|
|
||||||
control.icon:SetTexture(texture)
|
|
||||||
data.setFunc(texture)
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
end, LAM.util.GetStringFromValue(choicesTooltips[i]))
|
|
||||||
addedChoices[texture] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function IsDisabled(control)
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
return control.data.disabled()
|
|
||||||
else
|
|
||||||
return control.data.disabled
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function SetColor(control, color)
|
|
||||||
local icon = control.icon
|
|
||||||
if IsDisabled(control) then
|
|
||||||
icon:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
icon.color = color or control.data.defaultColor or ZO_DEFAULT_ENABLED_COLOR
|
|
||||||
icon:SetColor(icon.color:UnpackRGBA())
|
|
||||||
end
|
|
||||||
|
|
||||||
local iconPicker = LAM.util.GetIconPickerMenu()
|
|
||||||
if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
|
|
||||||
iconPicker:SetColor(icon.color)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable = IsDisabled(control)
|
|
||||||
|
|
||||||
control.dropdown:SetMouseEnabled(not disable)
|
|
||||||
control.dropdownButton:SetEnabled(not disable)
|
|
||||||
|
|
||||||
local iconPicker = LAM.util.GetIconPickerMenu()
|
|
||||||
if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
|
|
||||||
iconPicker:Clear()
|
|
||||||
end
|
|
||||||
|
|
||||||
SetColor(control, control.icon.color)
|
|
||||||
if disable then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, value)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
value = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
control.data.setFunc(value)
|
|
||||||
control.icon:SetTexture(value)
|
|
||||||
elseif value then
|
|
||||||
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
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
value = control.data.getFunc()
|
|
||||||
control.icon:SetTexture(value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 26
|
|
||||||
local HALF_WIDTH_LINE_SPACING = 2
|
|
||||||
local function SetIconSize(control, size)
|
|
||||||
local icon = control.icon
|
|
||||||
icon.size = size
|
|
||||||
icon:SetDimensions(size, size)
|
|
||||||
|
|
||||||
local height = size + 4
|
|
||||||
control.dropdown:SetDimensions(size + 20, height)
|
|
||||||
height = math.max(height, MIN_HEIGHT)
|
|
||||||
control.container:SetHeight(height)
|
|
||||||
if control.lineControl then
|
|
||||||
control.lineControl:SetHeight(MIN_HEIGHT + size + HALF_WIDTH_LINE_SPACING)
|
|
||||||
else
|
|
||||||
control:SetHeight(height)
|
|
||||||
end
|
|
||||||
|
|
||||||
local iconPicker = LAM.util.GetIconPickerMenu()
|
|
||||||
if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
|
|
||||||
iconPicker:SetIconSize(size)
|
|
||||||
iconPicker:UpdateDimensions()
|
|
||||||
iconPicker:UpdateAnchors()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.iconpicker(parent, iconpickerData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, iconpickerData, controlName)
|
|
||||||
|
|
||||||
local function ShowIconPicker()
|
|
||||||
local iconPicker = LAM.util.GetIconPickerMenu()
|
|
||||||
if iconPicker.parent == control.container then
|
|
||||||
iconPicker:Clear()
|
|
||||||
else
|
|
||||||
iconPicker:SetMaxColumns(iconpickerData.maxColumns)
|
|
||||||
iconPicker:SetVisibleRows(iconpickerData.visibleRows)
|
|
||||||
iconPicker:SetIconSize(control.icon.size)
|
|
||||||
UpdateChoices(control)
|
|
||||||
iconPicker:SetColor(control.icon.color)
|
|
||||||
if iconpickerData.beforeShow then
|
|
||||||
if iconpickerData.beforeShow(control, iconPicker) then
|
|
||||||
iconPicker:Clear()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
iconPicker:Show(control.container)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local iconSize = iconpickerData.iconSize ~= nil and iconpickerData.iconSize or DEFAULT_SIZE
|
|
||||||
control.dropdown = wm:CreateControl(nil, control.container, CT_CONTROL)
|
|
||||||
local dropdown = control.dropdown
|
|
||||||
dropdown:SetAnchor(LEFT, control.container, LEFT, 0, 0)
|
|
||||||
dropdown:SetMouseEnabled(true)
|
|
||||||
dropdown:SetHandler("OnMouseUp", ShowIconPicker)
|
|
||||||
dropdown:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
|
|
||||||
dropdown:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
|
|
||||||
|
|
||||||
control.icon = wm:CreateControl(nil, dropdown, CT_TEXTURE)
|
|
||||||
local icon = control.icon
|
|
||||||
icon:SetAnchor(LEFT, dropdown, LEFT, 3, 0)
|
|
||||||
icon:SetDrawLevel(2)
|
|
||||||
|
|
||||||
local dropdownButton = wm:CreateControlFromVirtual(nil, dropdown, "ZO_DropdownButton")
|
|
||||||
dropdownButton:SetDimensions(16, 16)
|
|
||||||
dropdownButton:SetHandler("OnClicked", ShowIconPicker)
|
|
||||||
dropdownButton:SetAnchor(RIGHT, dropdown, RIGHT, -3, 0)
|
|
||||||
control.dropdownButton = dropdownButton
|
|
||||||
|
|
||||||
control.bg = wm:CreateControl(nil, dropdown, CT_BACKDROP)
|
|
||||||
local bg = control.bg
|
|
||||||
bg:SetAnchor(TOPLEFT, dropdown, TOPLEFT, 0, -3)
|
|
||||||
bg:SetAnchor(BOTTOMRIGHT, dropdown, BOTTOMRIGHT, 2, 5)
|
|
||||||
bg:SetEdgeTexture("EsoUI/Art/Tooltips/UI-Border.dds", 128, 16)
|
|
||||||
bg:SetCenterTexture("EsoUI/Art/Tooltips/UI-TooltipCenter.dds")
|
|
||||||
bg:SetInsets(16, 16, -16, -16)
|
|
||||||
local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
|
|
||||||
mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
|
|
||||||
mungeOverlay:SetDrawLevel(1)
|
|
||||||
mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
|
|
||||||
mungeOverlay:SetAnchorFill()
|
|
||||||
|
|
||||||
if iconpickerData.warning ~= nil or iconpickerData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, control.container, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.UpdateChoices = UpdateChoices
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
control.SetColor = SetColor
|
|
||||||
control:SetColor()
|
|
||||||
control.SetIconSize = SetIconSize
|
|
||||||
control:SetIconSize(iconSize)
|
|
||||||
|
|
||||||
if iconpickerData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,168 +0,0 @@
|
|||||||
--[[panelData = {
|
|
||||||
type = "panel",
|
|
||||||
name = "Window Title", -- or string id or function returning a string
|
|
||||||
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)
|
|
||||||
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 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)
|
|
||||||
slashCommand = "/myaddon", -- will register a keybind to open to this panel (don't forget to include the slash!) (optional)
|
|
||||||
registerForRefresh = true, -- boolean will refresh all options controls when a setting is changed and when the panel is shown (optional)
|
|
||||||
registerForDefaults = true, -- boolean will set all options controls back to default values (optional)
|
|
||||||
resetFunc = function() print("defaults reset") end, -- custom function to run after settings are reset to defaults (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
|
|
||||||
local widgetVersion = 15
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("panel", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
local cm = CALLBACK_MANAGER
|
|
||||||
|
|
||||||
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
|
|
||||||
if LAM.currentAddonPanel ~= panel or not LAM.currentPanelOpened then return end -- we refresh it later when the panel is opened
|
|
||||||
|
|
||||||
local panelControls = panel.controlsToRefresh
|
|
||||||
|
|
||||||
for i = 1, #panelControls do
|
|
||||||
local updateControl = panelControls[i]
|
|
||||||
if updateControl ~= control and updateControl.UpdateValue then
|
|
||||||
updateControl:UpdateValue()
|
|
||||||
end
|
|
||||||
if updateControl.UpdateDisabled then
|
|
||||||
updateControl:UpdateDisabled()
|
|
||||||
end
|
|
||||||
if updateControl.UpdateWarning then
|
|
||||||
updateControl:UpdateWarning()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ForceDefaults(panel)
|
|
||||||
local panelControls = panel.controlsToRefresh
|
|
||||||
|
|
||||||
for i = 1, #panelControls do
|
|
||||||
local updateControl = panelControls[i]
|
|
||||||
if updateControl.UpdateValue and updateControl.data.default ~= nil then
|
|
||||||
updateControl:UpdateValue(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if panel.data.resetFunc then
|
|
||||||
panel.data.resetFunc()
|
|
||||||
end
|
|
||||||
|
|
||||||
cm:FireCallbacks("LAM-RefreshPanel", panel)
|
|
||||||
end
|
|
||||||
|
|
||||||
local callbackRegistered = false
|
|
||||||
LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
|
|
||||||
local SEPARATOR = " - "
|
|
||||||
local COLORED_SEPARATOR = ZO_WHITE:Colorize(SEPARATOR)
|
|
||||||
local LINK_COLOR = ZO_ColorDef:New("5959D5")
|
|
||||||
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)
|
|
||||||
local control = wm:CreateControl(controlName, parent, CT_CONTROL)
|
|
||||||
|
|
||||||
control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
|
|
||||||
local label = control.label
|
|
||||||
label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 4)
|
|
||||||
label:SetText(LAM.util.GetStringFromValue(panelData.displayName or panelData.name))
|
|
||||||
|
|
||||||
local previousInfoControl
|
|
||||||
if panelData.author or panelData.version then
|
|
||||||
control.info = wm:CreateControl(nil, control, CT_LABEL)
|
|
||||||
local info = control.info
|
|
||||||
info:SetFont(LAM.util.L["PANEL_INFO_FONT"])
|
|
||||||
info:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
|
|
||||||
|
|
||||||
local output = {}
|
|
||||||
if panelData.author then
|
|
||||||
output[#output + 1] = zo_strformat(LAM.util.L["AUTHOR"], LAM.util.GetStringFromValue(panelData.author))
|
|
||||||
end
|
|
||||||
if panelData.version then
|
|
||||||
output[#output + 1] = zo_strformat(LAM.util.L["VERSION"], LAM.util.GetStringFromValue(panelData.version))
|
|
||||||
end
|
|
||||||
info:SetText(table.concat(output, SEPARATOR))
|
|
||||||
previousInfoControl = info
|
|
||||||
end
|
|
||||||
|
|
||||||
if panelData.website then
|
|
||||||
control.website = CreateButtonControl(control, LAM.util.L["WEBSITE"], panelData.website, previousInfoControl)
|
|
||||||
previousInfoControl = control.website
|
|
||||||
end
|
|
||||||
|
|
||||||
if panelData.feedback then
|
|
||||||
control.feedback = CreateButtonControl(control, LAM.util.L["FEEDBACK"], panelData.feedback, previousInfoControl)
|
|
||||||
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
|
|
||||||
|
|
||||||
control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
|
|
||||||
LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1
|
|
||||||
local container = control.container
|
|
||||||
container:SetAnchor(TOPLEFT, control.info or label, BOTTOMLEFT, 0, 20)
|
|
||||||
container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3)
|
|
||||||
control.scroll = GetControl(control.container, "ScrollChild")
|
|
||||||
control.scroll:SetResizeToFitPadding(0, 20)
|
|
||||||
|
|
||||||
if panelData.registerForRefresh and not callbackRegistered then --don't want to register our callback more than once
|
|
||||||
cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel)
|
|
||||||
callbackRegistered = true
|
|
||||||
end
|
|
||||||
|
|
||||||
control.ForceDefaults = ForceDefaults
|
|
||||||
control.RefreshPanel = LAM.util.RequestRefreshIfNeeded
|
|
||||||
control.data = panelData
|
|
||||||
control.controlsToRefresh = {}
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,220 +0,0 @@
|
|||||||
--[[sliderData = {
|
|
||||||
type = "slider",
|
|
||||||
name = "My Slider", -- or string id or function returning a string
|
|
||||||
getFunc = function() return db.var end,
|
|
||||||
setFunc = function(value) db.var = value doStuff() end,
|
|
||||||
min = 0,
|
|
||||||
max = 20,
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
disabled = function() return db.someBooleanSetting end, --or boolean (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)
|
|
||||||
default = defaults.var, -- default value or function that returns the default value (optional)
|
|
||||||
reference = "MyAddonSlider" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
local widgetVersion = 13
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("slider", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
local strformat = string.format
|
|
||||||
|
|
||||||
local function RoundDecimalToPlace(d, place)
|
|
||||||
return tonumber(strformat("%." .. tostring(place) .. "f", d))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ClampValue(value, min, max)
|
|
||||||
return math.max(math.min(value, max), min)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateDisabled(control)
|
|
||||||
local disable
|
|
||||||
if type(control.data.disabled) == "function" then
|
|
||||||
disable = control.data.disabled()
|
|
||||||
else
|
|
||||||
disable = control.data.disabled
|
|
||||||
end
|
|
||||||
|
|
||||||
control.slider:SetEnabled(not disable)
|
|
||||||
control.slidervalue:SetEditEnabled(not disable)
|
|
||||||
if disable then
|
|
||||||
control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
|
|
||||||
control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
|
|
||||||
else
|
|
||||||
control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function UpdateValue(control, forceDefault, value)
|
|
||||||
if forceDefault then --if we are forcing defaults
|
|
||||||
value = LAM.util.GetDefaultValue(control.data.default)
|
|
||||||
control.data.setFunc(value)
|
|
||||||
elseif value then
|
|
||||||
if control.data.decimals then
|
|
||||||
value = RoundDecimalToPlace(value, control.data.decimals)
|
|
||||||
end
|
|
||||||
if control.data.clampInput ~= false then
|
|
||||||
local clamp = control.data.clampFunction or ClampValue
|
|
||||||
value = clamp(value, control.data.min, control.data.max)
|
|
||||||
end
|
|
||||||
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
|
|
||||||
LAM.util.RequestRefreshIfNeeded(control)
|
|
||||||
else
|
|
||||||
value = control.data.getFunc()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.slider:SetValue(value)
|
|
||||||
control.slidervalue:SetText(value)
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.slider(parent, sliderData, controlName)
|
|
||||||
local control = LAM.util.CreateLabelAndContainerControl(parent, sliderData, controlName)
|
|
||||||
local isInputOnRight = sliderData.inputLocation == "right"
|
|
||||||
|
|
||||||
--skipping creating the backdrop... Is this the actual slider texture?
|
|
||||||
control.slider = wm:CreateControl(nil, control.container, CT_SLIDER)
|
|
||||||
local slider = control.slider
|
|
||||||
slider:SetAnchor(TOPLEFT)
|
|
||||||
slider:SetHeight(14)
|
|
||||||
if(isInputOnRight) then
|
|
||||||
slider:SetAnchor(TOPRIGHT, nil, nil, -60)
|
|
||||||
else
|
|
||||||
slider:SetAnchor(TOPRIGHT)
|
|
||||||
end
|
|
||||||
slider:SetMouseEnabled(true)
|
|
||||||
slider:SetOrientation(ORIENTATION_HORIZONTAL)
|
|
||||||
--put nil for highlighted texture file path, and what look to be texture coords
|
|
||||||
slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16)
|
|
||||||
local minValue = sliderData.min
|
|
||||||
local maxValue = sliderData.max
|
|
||||||
slider:SetMinMax(minValue, maxValue)
|
|
||||||
slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
|
|
||||||
slider:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
|
|
||||||
|
|
||||||
slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP)
|
|
||||||
local bg = slider.bg
|
|
||||||
bg:SetCenterColor(0, 0, 0)
|
|
||||||
bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4)
|
|
||||||
bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4)
|
|
||||||
bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)
|
|
||||||
|
|
||||||
control.minText = wm:CreateControl(nil, slider, CT_LABEL)
|
|
||||||
local minText = control.minText
|
|
||||||
minText:SetFont("ZoFontGameSmall")
|
|
||||||
minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT)
|
|
||||||
minText:SetText(sliderData.min)
|
|
||||||
|
|
||||||
control.maxText = wm:CreateControl(nil, slider, CT_LABEL)
|
|
||||||
local maxText = control.maxText
|
|
||||||
maxText:SetFont("ZoFontGameSmall")
|
|
||||||
maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT)
|
|
||||||
maxText:SetText(sliderData.max)
|
|
||||||
|
|
||||||
control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop")
|
|
||||||
if(isInputOnRight) then
|
|
||||||
control.slidervalueBG:SetDimensions(60, 26)
|
|
||||||
control.slidervalueBG:SetAnchor(LEFT, slider, RIGHT, 5, 0)
|
|
||||||
else
|
|
||||||
control.slidervalueBG:SetDimensions(50, 16)
|
|
||||||
control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
|
|
||||||
end
|
|
||||||
control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")
|
|
||||||
local slidervalue = control.slidervalue
|
|
||||||
slidervalue:ClearAnchors()
|
|
||||||
slidervalue:SetAnchor(TOPLEFT, control.slidervalueBG, TOPLEFT, 3, 1)
|
|
||||||
slidervalue:SetAnchor(BOTTOMRIGHT, control.slidervalueBG, BOTTOMRIGHT, -3, -1)
|
|
||||||
slidervalue:SetTextType(TEXT_TYPE_NUMERIC)
|
|
||||||
if(isInputOnRight) then
|
|
||||||
slidervalue:SetFont("ZoFontGameLarge")
|
|
||||||
else
|
|
||||||
slidervalue:SetFont("ZoFontGameSmall")
|
|
||||||
end
|
|
||||||
|
|
||||||
local isHandlingChange = false
|
|
||||||
local function HandleValueChanged(value)
|
|
||||||
if isHandlingChange then return end
|
|
||||||
if sliderData.decimals then
|
|
||||||
value = RoundDecimalToPlace(value, sliderData.decimals)
|
|
||||||
end
|
|
||||||
isHandlingChange = true
|
|
||||||
slider:SetValue(value)
|
|
||||||
slidervalue:SetText(value)
|
|
||||||
isHandlingChange = false
|
|
||||||
end
|
|
||||||
|
|
||||||
slidervalue:SetHandler("OnEscape", function(self)
|
|
||||||
HandleValueChanged(sliderData.getFunc())
|
|
||||||
self:LoseFocus()
|
|
||||||
end)
|
|
||||||
slidervalue:SetHandler("OnEnter", function(self)
|
|
||||||
self:LoseFocus()
|
|
||||||
end)
|
|
||||||
slidervalue:SetHandler("OnFocusLost", function(self)
|
|
||||||
local value = tonumber(self:GetText())
|
|
||||||
control:UpdateValue(false, value)
|
|
||||||
end)
|
|
||||||
slidervalue:SetHandler("OnTextChanged", function(self)
|
|
||||||
local input = self:GetText()
|
|
||||||
if(#input > 1 and not input:sub(-1):match("[0-9]")) then return end
|
|
||||||
local value = tonumber(input)
|
|
||||||
if(value) then
|
|
||||||
HandleValueChanged(value)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
if(sliderData.autoSelect) then
|
|
||||||
ZO_PreHookHandler(slidervalue, "OnFocusGained", function(self)
|
|
||||||
self:SelectAll()
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
local range = maxValue - minValue
|
|
||||||
slider:SetValueStep(sliderData.step or 1)
|
|
||||||
slider:SetHandler("OnValueChanged", function(self, value, eventReason)
|
|
||||||
if eventReason == EVENT_REASON_SOFTWARE then return end
|
|
||||||
HandleValueChanged(value)
|
|
||||||
end)
|
|
||||||
slider:SetHandler("OnSliderReleased", function(self, value)
|
|
||||||
if self:GetEnabled() then
|
|
||||||
control:UpdateValue(false, value)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
slider:SetHandler("OnMouseWheel", function(self, value)
|
|
||||||
if(not self:GetEnabled()) then return end
|
|
||||||
local new_value = (tonumber(slidervalue:GetText()) or sliderData.min or 0) + ((sliderData.step or 1) * value)
|
|
||||||
control:UpdateValue(false, new_value)
|
|
||||||
end)
|
|
||||||
|
|
||||||
if sliderData.warning ~= nil or sliderData.requiresReload then
|
|
||||||
control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
|
|
||||||
control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0)
|
|
||||||
control.UpdateWarning = LAM.util.UpdateWarning
|
|
||||||
control:UpdateWarning()
|
|
||||||
end
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
control:UpdateValue()
|
|
||||||
|
|
||||||
if sliderData.disabled ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
LAM.util.RegisterForReloadIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,182 +0,0 @@
|
|||||||
--[[submenuData = {
|
|
||||||
type = "submenu",
|
|
||||||
name = "Submenu Title", -- or string id or function returning a string
|
|
||||||
icon = "path/to/my/icon.dds", -- or function returning a string (optional)
|
|
||||||
iconTextureCoords = {left, right, top, bottom}, -- or function returning a table (optional)
|
|
||||||
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 = 13
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("submenu", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_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)
|
|
||||||
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
|
|
||||||
control.label.data.tooltipText = LAM.util.GetStringFromValue(control.data.tooltip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function AnimateSubmenu(clicked)
|
|
||||||
local control = clicked:GetParent()
|
|
||||||
if control.disabled then return end
|
|
||||||
|
|
||||||
control.open = not control.open
|
|
||||||
if control.open then
|
|
||||||
control.animation:PlayFromStart()
|
|
||||||
else
|
|
||||||
control.animation:PlayFromEnd()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function LAMCreateControl.submenu(parent, submenuData, controlName)
|
|
||||||
local width = parent:GetWidth() - 45
|
|
||||||
local control = wm:CreateControl(controlName or submenuData.reference, parent.scroll or parent, CT_CONTROL)
|
|
||||||
control.panel = parent
|
|
||||||
control.data = submenuData
|
|
||||||
|
|
||||||
control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
|
|
||||||
local label = control.label
|
|
||||||
label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
|
|
||||||
label:SetText(LAM.util.GetStringFromValue(submenuData.name))
|
|
||||||
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
|
|
||||||
label.data = {tooltipText = LAM.util.GetStringFromValue(submenuData.tooltip)}
|
|
||||||
label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
|
|
||||||
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
|
|
||||||
|
|
||||||
control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
|
|
||||||
local scroll = control.scroll
|
|
||||||
scroll:SetParent(control)
|
|
||||||
scroll:SetAnchor(TOPLEFT, control.icon or label, BOTTOMLEFT, 0, 10)
|
|
||||||
scroll:SetDimensionConstraints(width + 5, 0, width + 5, 0)
|
|
||||||
|
|
||||||
control.bg = wm:CreateControl(nil, control.icon or label, CT_BACKDROP)
|
|
||||||
local bg = control.bg
|
|
||||||
bg:SetAnchor(TOPLEFT, control.icon or label, TOPLEFT, -5, -5)
|
|
||||||
bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
|
|
||||||
bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
|
|
||||||
bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
|
|
||||||
bg:SetInsets(16, 16, -16, -16)
|
|
||||||
bg:SetDrawLayer(DL_BACKGROUND)
|
|
||||||
|
|
||||||
control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
|
|
||||||
local arrow = control.arrow
|
|
||||||
arrow:SetDimensions(28, 28)
|
|
||||||
arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds") --list_sortup for the other way
|
|
||||||
arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5)
|
|
||||||
|
|
||||||
--figure out the cool animation later...
|
|
||||||
control.animation = am:CreateTimeline()
|
|
||||||
local animation = control.animation
|
|
||||||
animation:SetPlaybackType(ANIMATION_SIZE, 0) --2nd arg = loop count
|
|
||||||
|
|
||||||
control:SetResizeToFitDescendents(true)
|
|
||||||
control.open = false
|
|
||||||
label:SetHandler("OnMouseUp", AnimateSubmenu)
|
|
||||||
if(control.icon) then
|
|
||||||
control.icon:SetHandler("OnMouseUp", AnimateSubmenu)
|
|
||||||
end
|
|
||||||
animation:SetHandler("OnStop", function(self, completedPlaying)
|
|
||||||
scroll:SetResizeToFitDescendents(control.open)
|
|
||||||
if control.open then
|
|
||||||
control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds")
|
|
||||||
scroll:SetResizeToFitPadding(5, 20)
|
|
||||||
else
|
|
||||||
control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")
|
|
||||||
scroll:SetResizeToFitPadding(5, 0)
|
|
||||||
scroll:SetHeight(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--small strip at the bottom of the submenu that you can click to close it
|
|
||||||
control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE)
|
|
||||||
local btmToggle = control.btmToggle
|
|
||||||
btmToggle:SetMouseEnabled(true)
|
|
||||||
btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT)
|
|
||||||
btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT)
|
|
||||||
btmToggle:SetHeight(15)
|
|
||||||
btmToggle:SetAlpha(0)
|
|
||||||
btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
|
|
||||||
|
|
||||||
control.UpdateValue = UpdateValue
|
|
||||||
if submenuData.disabled ~= nil or submenuData.disabledLabel ~= nil then
|
|
||||||
control.UpdateDisabled = UpdateDisabled
|
|
||||||
control:UpdateDisabled()
|
|
||||||
end
|
|
||||||
|
|
||||||
LAM.util.RegisterForRefreshIfNeeded(control)
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,45 +0,0 @@
|
|||||||
--[[textureData = {
|
|
||||||
type = "texture",
|
|
||||||
image = "file/path.dds",
|
|
||||||
imageWidth = 64, -- max of 250 for half width, 510 for full
|
|
||||||
imageHeight = 32, -- max of 100
|
|
||||||
tooltip = "Image's tooltip text.", -- or string id or function returning a string (optional)
|
|
||||||
width = "full", -- or "half" (optional)
|
|
||||||
reference = "MyAddonTexture" -- unique global reference to control (optional)
|
|
||||||
} ]]
|
|
||||||
|
|
||||||
-- TODO: add texture coords support?
|
|
||||||
|
|
||||||
local widgetVersion = 9
|
|
||||||
local LAM = LibStub("LibAddonMenu-2.0")
|
|
||||||
if not LAM:RegisterWidget("texture", widgetVersion) then return end
|
|
||||||
|
|
||||||
local wm = WINDOW_MANAGER
|
|
||||||
|
|
||||||
local MIN_HEIGHT = 26
|
|
||||||
function LAMCreateControl.texture(parent, textureData, controlName)
|
|
||||||
local control = LAM.util.CreateBaseControl(parent, textureData, controlName)
|
|
||||||
local width = control:GetWidth()
|
|
||||||
control:SetResizeToFitDescendents(true)
|
|
||||||
|
|
||||||
if control.isHalfWidth then --note these restrictions
|
|
||||||
control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
|
|
||||||
else
|
|
||||||
control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
|
|
||||||
end
|
|
||||||
|
|
||||||
control.texture = wm:CreateControl(nil, control, CT_TEXTURE)
|
|
||||||
local texture = control.texture
|
|
||||||
texture:SetAnchor(CENTER)
|
|
||||||
texture:SetDimensions(textureData.imageWidth, textureData.imageHeight)
|
|
||||||
texture:SetTexture(textureData.image)
|
|
||||||
|
|
||||||
if textureData.tooltip then
|
|
||||||
texture:SetMouseEnabled(true)
|
|
||||||
texture.data = {tooltipText = LAM.util.GetStringFromValue(textureData.tooltip)}
|
|
||||||
texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
|
|
||||||
texture:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
|
|
||||||
end
|
|
||||||
|
|
||||||
return control
|
|
||||||
end
|
|
@ -1,38 +0,0 @@
|
|||||||
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
|
|
||||||
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
|
|
||||||
-- LibStub developed for World of Warcraft by above members of the WowAce community.
|
|
||||||
-- Ported to Elder Scrolls Online by Seerah
|
|
||||||
|
|
||||||
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 5
|
|
||||||
local LibStub = _G[LIBSTUB_MAJOR]
|
|
||||||
|
|
||||||
local strformat = string.format
|
|
||||||
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
|
|
||||||
LibStub = LibStub or {libs = {}, minors = {} }
|
|
||||||
_G[LIBSTUB_MAJOR] = LibStub
|
|
||||||
LibStub.minor = LIBSTUB_MINOR
|
|
||||||
|
|
||||||
function LibStub:NewLibrary(major, minor)
|
|
||||||
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
|
|
||||||
if type(minor) ~= "number" then
|
|
||||||
minor = assert(tonumber(zo_strmatch(minor, "%d+%.?%d*")), "Minor version must either be a number or contain a number.")
|
|
||||||
end
|
|
||||||
|
|
||||||
local oldminor = self.minors[major]
|
|
||||||
if oldminor and oldminor >= minor then return nil end
|
|
||||||
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
|
|
||||||
return self.libs[major], oldminor
|
|
||||||
end
|
|
||||||
|
|
||||||
function LibStub:GetLibrary(major, silent)
|
|
||||||
if not self.libs[major] and not silent then
|
|
||||||
error(strformat("Cannot find a library instance of %q.", tostring(major)), 2)
|
|
||||||
end
|
|
||||||
return self.libs[major], self.minors[major]
|
|
||||||
end
|
|
||||||
|
|
||||||
function LibStub:IterateLibraries() return pairs(self.libs) end
|
|
||||||
setmetatable(LibStub, { __call = LibStub.GetLibrary })
|
|
||||||
end
|
|
||||||
|
|
||||||
LibStub.SILENT = true
|
|
35
README.md
35
README.md
@ -1,12 +1,33 @@
|
|||||||
# AchievementInfo
|
# AchievementInfo
|
||||||
|
|
||||||
[![Build Status](https://drone.f-brinker.de/api/badges/fbrinker/elderscrolls-addon-achievementInfo/status.svg)](https://drone.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo)
|
[![Version Status](https://monitoring.f-brinker.de/api/badge/18/status?style=plastic&upLabel=Up%20to%20date&downLabel=Outdated)](https://monitoring.f-brinker.de/status/eso)
|
||||||
[![Latest Releases](https://badgen.net/badge/releases/latest)](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/releases)
|
[![Build Status](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/actions/workflows/build.yaml/badge.svg)](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/actions)
|
||||||
|
|
||||||
This is an **The Elderscrolls Online** addon. [See all details and the download @ESOUI](http://www.esoui.com/downloads/info350-AchievementInfo.html#info).
|
[![Latest Releases](https://badgen.net/badge/releases/latest)](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/releases)
|
||||||
|
[![Downloads](https://badgen.net/https/scripts.f-brinker.de/esoui-stats/badge-total.php?cache=1800)](https://www.esoui.com/downloads/info350-AchievementInfo.html)
|
||||||
|
[![Favorites](https://badgen.net/https/scripts.f-brinker.de/esoui-stats/badge-fav.php?cache=1800)](https://www.esoui.com/downloads/info350-AchievementInfo.html)
|
||||||
|
|
||||||
|
This is a **The Elderscrolls Online** addon. [See all details and the download @ESOUI](http://www.esoui.com/downloads/info350-AchievementInfo.html#info).
|
||||||
|
|
||||||
[Issue-Tracker](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/issues)
|
[Issue-Tracker](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo/issues)
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
### What is this AddOn about?
|
||||||
|
|
||||||
|
I like achievements, and I like to know what to do to complete them and what type of achievements exist without browsing through the entire achievement catalog: This AddOn displays lightweight chat notifications if you make progress in an achievement (please see the screenshots).
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Shows chat notifications if you do something that is needed for an achievement
|
||||||
|
* Triggers on each action or just in x% steps of the achievement's requirements (configurable)
|
||||||
|
* Can show some details in the chat notification like (kill 250/1000 Humanoids)
|
||||||
|
* You can toggle the notifications for each category
|
||||||
|
* Lightweight: It is not always present and shows up only when necessary
|
||||||
|
* You can enable account-wide settings
|
||||||
|
|
||||||
|
![preview screenshot](screenshots/chat-1.jpg)
|
||||||
|
|
||||||
## Why is this a public project?
|
## Why is this a public project?
|
||||||
|
|
||||||
In case I quit or pause playing TESO and cannot maintain this addon, feel free to contribute to keep this up to date and running.
|
In case I quit or pause playing TESO and cannot maintain this addon, feel free to contribute to keep this up to date and running.
|
||||||
@ -16,7 +37,13 @@ I'll still be available here and be able to update the ESOUI page.
|
|||||||
|
|
||||||
**IMPORTANT: Github is a mirror.** Please contribute at [git.f-brinker.de/elderscrolls-addon-achievementInfo](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo) - You can log in with your Github or Gitlab account (OAuth2).
|
**IMPORTANT: Github is a mirror.** Please contribute at [git.f-brinker.de/elderscrolls-addon-achievementInfo](https://git.f-brinker.de/fbrinker/elderscrolls-addon-achievementInfo) - You can log in with your Github or Gitlab account (OAuth2).
|
||||||
|
|
||||||
Then, create a fork of the repository, do what you have to do and create a pull-request afterwards. Feel free to contact me any time.
|
Then, create a fork of the repository, do what you have to do, and create a pull-request afterward. Feel free to contact me any time.
|
||||||
|
|
||||||
#### Linting
|
#### Linting
|
||||||
Luacheck is used to check the LUA code. [Documentation](https://luacheck.readthedocs.io/en/stable/index.html)
|
Luacheck is used to check the LUA code. [Documentation](https://luacheck.readthedocs.io/en/stable/index.html)
|
||||||
|
|
||||||
|
## API Version Upgrade
|
||||||
|
* Increment the API Version in the _AchievementInfo.txt_ file
|
||||||
|
* Commit: `git commit -am "New Api Version"`
|
||||||
|
* Add new Tag `git tag x.yz`
|
||||||
|
* Push `git push && git push --tags`
|
BIN
screenshots/chat-1.jpg
Normal file
BIN
screenshots/chat-1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
screenshots/chat-2.jpg
Normal file
BIN
screenshots/chat-2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
screenshots/settings.jpg
Normal file
BIN
screenshots/settings.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
Loading…
Reference in New Issue
Block a user