4 Commits
1.0.0 ... 1.1.3

Author SHA1 Message Date
551744a2eb Version 1.1.3
- bumped version for all versions of WoW (Classic Era, Season of Mastery, BCC, Retail)
- error on missing options at first start
- updated Ace3.0 libraries for latest Shadowlands patch
2021-10-06 02:36:53 +02:00
68da0b15bb Version 1.1.2a
- adopt to BigWigs release script
2021-05-23 21:34:48 +02:00
06a1f1177a Version 1.1.1
- bumped versions for WoW Classic and Shadowlands
2021-04-22 16:53:22 +02:00
475b2b3e1f Version 1.1.0
- split of messages preserves item links, textures, substitutions and raid target markers
- added safety measures to prevent endless replacement loops
- bumped version for Shadowlands
- bumped version for Naxxramas
- split of messages with excessive length no longer causes errors or broken texts
- proper handling of umlauts
2020-12-08 19:32:14 +01:00
44 changed files with 3846 additions and 580 deletions

1
.gitignore vendored
View File

@@ -38,6 +38,7 @@ obj/
# Misc # Misc
.bin/ .bin/
.release/
*.log *.log
*.graphml *.graphml
coverage.db* coverage.db*

View File

@@ -2,23 +2,29 @@ package-as: Grichelde
enable-nolib-creation: no enable-nolib-creation: no
externals: embedded-libraries:
libs/LibStub: https://repos.wowace.com/wow/libstub/tags/1.0 Libs/LibStub: https://repos.wowace.com/wow/libstub/tags/1.0
libs/LibDataBroker: https://github.com/tekkub/libdatabroker-1-1 curse-slug: libstub
libs/LibDBIcon: https://repos.curseforge.com/wow/libdbicon-1-0/trunk/LibDBIcon-1.0 Libs/LibDataBroker: https://github.com/tekkub/libdatabroker-1-1
libs/CallbackHandler-1.0: https://repos.wowace.com/wow/callbackhandler/trunk/CallbackHandler-1.0 curse-slug: libdatabroker-1-1
libs/AceAddon-3.0: https://repos.wowace.com/wow/ace3/trunk/AceAddon-3.0 Libs/LibDBIcon: https://repos.curseforge.com/wow/libdbicon-1-0/trunk/LibDBIcon-1.0
libs/AceConfig-3.0: https://repos.wowace.com/wow/ace3/trunk/AceConfig-3.0 curse-slug: libdbicon-1-0
libs/AceConsole-3.0: https://repos.wowace.com/wow/ace3/trunk/AceConsole-3.0 Libs/CallbackHandler-1.0: https://repos.wowace.com/wow/callbackhandler/trunk/CallbackHandler-1.0
libs/AceDB-3.0: https://repos.wowace.com/wow/ace3/trunk/AceDB-3.0 curse-slug: callbackhandler
libs/AceDBOptions-3.0: https://repos.wowace.com/wow/ace3/trunk/AceDBOptions-3.0 Libs/AceAddon-3.0: https://repos.wowace.com/wow/ace3/trunk/AceAddon-3.0
libs/AceEvent-3.0: https://repos.wowace.com/wow/ace3/trunk/AceEvent-3.0 curse-slug: ace3
libs/AceGUI-3.0: https://repos.wowace.com/wow/ace3/trunk/AceGUI-3.0 Libs/AceConfig-3.0: https://repos.wowace.com/wow/ace3/trunk/AceConfig-3.0
libs/AceHook-3.0: https://repos.wowace.com/wow/ace3/trunk/AceHook-3.0 Libs/AceConsole-3.0: https://repos.wowace.com/wow/ace3/trunk/AceConsole-3.0
libs/AceLocale-3.0: https://repos.wowace.com/wow/ace3/trunk/AceLocale-3.0 Libs/AceDB-3.0: https://repos.wowace.com/wow/ace3/trunk/AceDB-3.0
Libs/AceDBOptions-3.0: https://repos.wowace.com/wow/ace3/trunk/AceDBOptions-3.0
Libs/AceEvent-3.0: https://repos.wowace.com/wow/ace3/trunk/AceEvent-3.0
Libs/AceGUI-3.0: https://repos.wowace.com/wow/ace3/trunk/AceGUI-3.0
Libs/AceHook-3.0: https://repos.wowace.com/wow/ace3/trunk/AceHook-3.0
Libs/AceLocale-3.0: https://repos.wowace.com/wow/ace3/trunk/AceLocale-3.0
ignore: ignore:
- twitch - twitch
- GricheldeTest.lua
manual-changelog: manual-changelog:
filename: CHANGELOG.md filename: CHANGELOG.md

311
.release/README.md Normal file
View File

@@ -0,0 +1,311 @@
# release.sh
__release.sh__ generates an addon zip file from a Git, SVN, or Mercurial
checkout.
__release.sh__ works by creating a new project directory (*.release* by
default), copying files from the checkout into the project directory, checking
out external repositories then copying their files into the project directory,
then moves subdirectories into the project root. The project directory is then
zipped to create a distributable addon zip file which can also be uploaded to
CurseForge, WoWInterface, Wago, and GitHub (as a release).
__release.sh__ assumes that tags (Git annotated tags and SVN tags) are named for
the version numbers for the project. It will identify if the HEAD is tagged and
use that as the current version number. It will search back through parent
commits for the previous tag and generate a changelog containing the commits
since that tag.
## Building with GitHub Actions
For a full example workflow, please check out the [wiki page](https://github.com/BigWigsMods/packager/wiki/GitHub-Actions-workflow).
### Example using [options](#Usage)
```yaml
- uses: BigWigsMods/packager@v1
with:
args: -g classic -m .pkgmeta-classic
```
## Customizing the build
__release.sh__ uses the TOC file to determine the package name for the project.
You can also set the CurseForge project id (`-p`), the WoWInterface addon
id (`-w`) or the Wago project id (`-a`) by adding the following to the TOC file:
```toc
## X-Curse-Project-ID: 1234
## X-WoWI-ID: 5678
## X-Wago-ID: he54k6bL
```
Your CurseForge project id can be found on the addon page in the "About Project"
side box.
Your WoWInterface addon id is in the url for the addon, eg, the "5678"
in <https://wowinterface.com/downloads/info5678-MyAddon>.
Your Wago project id can be found on the developer dashboard.
### The PackageMeta file
__release.sh__ can read a __.pkgmeta__ file and supports the following
directives. See the [wiki page](https://github.com/BigWigsMods/packager/wiki/Preparing-the-PackageMeta-File)
for more info.
- *externals* (Git, SVN, and Mercurial) Caveats: An external's .pkgmeta is only
parsed for ignore and externals will not have localization keywords replaced.
- *ignore*
- *changelog-title*
- *manual-changelog*
- *move-folders*
- *package-as*
- *enable-nolib-creation* (defaults to no) Caveats: nolib packages will only be
uploaded to GitHub and attached to a release. Unlike with the CurseForge
packager, manually uploaded nolib packages will not be used by the client when
users have enabled downloading libraries separately.
- *tools-used*
- *required-dependencies*
- *optional-dependencies*
- *embedded-libraries* Note: All fetched externals will be marked as embedded,
overriding any manually set relations in the pkgmeta.
You can also use a few directives for WoWInterface uploading.
- *wowi-archive-previous* : `yes|no` (defaults to yes) Archive the previous
release.
- *wowi-create-changelog* : `yes|no` (defaults to yes) Generate a changelog
using BBCode that will be set when uploading. A manual changelog will always
be used instead if set in the .pkgmeta.
- *wowi-convert-changelog* : `yes|no` (defaults to yes) Convert a manual
changelog in Markdown format to BBCode if you have [pandoc](http://pandoc.org/)
installed; otherwise, the manual changelog will be used as-is. If set to `no`
when using a generated changelog, Markdown will be used instead of BBCode.
**Note**: Markdown support is experimental and needs to be requested on a
per-project basis.
### String replacements
__release.sh__ supports the following repository substitution keywords when
copying the files from the checkout into the project directory. See the
[wiki page](https://github.com/BigWigsMods/packager/wiki/Repository-Keyword-Substitutions)
for more info.
- *@[localization](https://github.com/BigWigsMods/packager/wiki/Localization-Substitution)(locale="locale", format="format", ...)@*
- *escape-non-ascii*
- *handle-unlocalized*
- *handle-subnamespaces="concat"*
- *key*
- *namespace*
- *same-key-is-true*
- *table-name*
- *@file-revision@*
- *@project-revision@*
- *@file-hash@*
- *@project-hash@*
- *@file-abbreviated-hash@*
- *@project-abbreviated-hash@*
- *@file-author@*
- *@project-author@*
- *@file-date-iso@*
- *@project-date-iso@*
- *@file-date-integer@*
- *@project-date-integer@*
- *@file-timestamp@*
- *@project-timestamp@*
- *@project-version@*
### Build type keywords
Specific keywords used in a comment at the start (`@keyword@`) and end
(`@end-keyword@`) of a block of code can be used to conditionally run that code
based on the build type. If the build type does not match, the block of code
is comment out so line numbers do not change.
Supported keywords and when the code block will run:
- `alpha`: in untagged builds.
- `debug`: never. Code will only run when using an unpackaged source.
- `do-not-package`: never. Same as `debug` except removed from the packaged
file.
- `no-lib-strip`: _(not supported in Lua files)_ in any build other than a
*nolib* build.
- `retail`,`version-retail`,`version-classic`,`version-bcc`: based on game
version.
`do-not-package` is a bit special. Everything between the tags, including the
tags themselves, will always be removed from the packaged file. This will cause
the line numbers of subsequent lines to change, which can result in bug report
line numbers not matching the source code. The typical usage is at the end of
Lua files surrounding debugging functions and other code that end users should
never see or execute.
All keywords except `do-not-package` can be prefixed with `non-` to inverse the
logic. When doing this, the keywords should start and end a **block comment**
as shown below.
More examples are available on the [wiki page](https://github.com/BigWigsMods/packager/wiki/Repository-Keyword-Substitutions#debug-replacements).
#### In Lua files
`--@keyword@` and `--@end-keyword@`
turn into `--[===[@keyword` and `--@end-keyword]===]`.
`--[===[@non-keyword@` and `--@end-non-keyword@]===]`
turn into `--@non-keyword@` and `--@end-non-keyword@`.
#### In XML files
**Note:** XML doesn't allow nested comments so make sure not to nest keywords.
If you need to nest keywords, you can do so in the TOC instead.
`<!--@keyword@-->` and `<!--@end-keyword@-->`
turn into `<!--@keyword` and `@end-keyword@-->`.
`<!--@non-keyword@` and `@end-non-keyword@-->`
turn into `<!--@non-keyword@-->` and `<!--@end-non-keyword@-->`.
#### In TOC files
The lines with `#@keyword@` and `#@end-keyword@` get removed, as well as every
line in-between.
The lines with `#@non-keyword@` and `#@end-non-keyword@` get removed, as well as
removing a '# ' at the beginning of each line in-between.
### Changing the file name
__release.sh__ uses the file name template `"{package-name}-{project-version}{nolib}{classic}"`
for the addon zip file. This can be changed with the `-n` switch (`release.sh
-n "{package-name}-{project-version}"`).
These tokens are always replaced with their value:
- `{package-name}`
- `{project-revision}`
- `{project-hash}`
- `{project-abbreviated-hash}`
- `{project-author}`
- `{project-date-iso}`
- `{project-date-integer}`
- `{project-timestamp}`
- `{project-version}`
- `{game-type}`
- `{release-type}`
These tokens are "flags" and are conditionally shown prefixed with a dash based
on the build type:
- `{alpha}`
- `{beta}`
- `{nolib}`
- `{classic}`
`{classic}` has some additional magic:
1. It will show as the non-retail build type, so either `-classic` or `-bcc`.
2. It will not be shown if "-classic" or "-bcc" is in the project version.
3. If it is included in the file name (it is by default) and #2 does not apply,
it will also be appended to the file label (i.e., the name shown on
CurseForge).
## Building for multiple game versions
__release.sh__ needs to know what version of World of Warcraft the package is
targeting. This is normally automatically detected using the `## Interface:`
line of the addon's TOC file.
If your addon supports both retail and classic in the same branch, you can use
multiple `## Interface-Type:` lines in your TOC file. Only one `## Interface:`
line will be included in the packaged TOC file based on the targeted game
version.
```toc
## Interface: 90005
## Interface-Retail: 90005
## Interface-Classic: 11306
## Interface-BCC: 20501
```
You specify what version of the game you're targeting with the `-g` switch. You
can use a specific version (`release.sh -g 1.13.6`) or you can use the game type
(`release.sh -g classic`). Using a game type will set the game version based on
the appropriate TOC `## Interface` value.
You can also set multiple specific versions as a comma delimited list using the
`-g` switch (`release.sh -g 1.13.6,2.5.1,9.0.5`). This will still only build
one package, with the the last version listed used as the target version for
the build.
**Setting multiple versions is not recommended!** The addon will always be
marked "Out of date" in-game for versions that do not match the TOC interface
value for the last version set. So even if you don't need any special file
processing, it will always be best to run the packager multiple times so the TOC
interface value is correct for each game version.
## Building locally
The recommended way to include __release.sh__ in a project is to:
1. Create a *.release* subdirectory in your top-level checkout.
2. Copy __release.sh__ into the *.release* directory.
3. Ignore the *.release* subdirectory in __.gitignore__.
4. Run __release.sh__.
## Usage
```text
Usage: release.sh [options]
-c Skip copying files into the package directory.
-d Skip uploading.
-e Skip checkout of external repositories.
-l Skip @localization@ keyword replacement.
-L Only do @localization@ keyword replacement (skip upload to CurseForge).
-o Keep existing package directory, overwriting its contents.
-s Create a stripped-down "nolib" package.
-u Use Unix line-endings.
-z Skip zip file creation.
-t topdir Set top-level directory of checkout.
-r releasedir Set directory containing the package directory. Defaults to "$topdir/.release".
-p curse-id Set the project id used on CurseForge for localization and uploading. (Use 0 to unset the TOC value)
-w wowi-id Set the addon id used on WoWInterface for uploading. (Use 0 to unset the TOC value)
-a wago-id Set the project id used on Wago Addons for uploading. (Use 0 to unset the TOC value)
-g game-version Set the game version to use for uploading.
-m pkgmeta.yaml Set the pkgmeta file to use.
-n package-name Set the package zip file name. Use "-n help" for more info.
```
### Uploading
__release.sh__ uses following environment variables for uploading:
- `CF_API_KEY` - a [CurseForge API token](https://wow.curseforge.com/account/api-tokens),
required for the CurseForge API to fetch localization and upload files.
- `WOWI_API_TOKEN` - a [WoWInterface API token](https://www.wowinterface.com/downloads/filecpl.php?action=apitokens),
required for uploading to WoWInterface.
- `WAGO_API_TOKEN` - a [Wago Addons API token](https://addons.wago.io/account/apikeys),
required for uploading to Wago Addons.
- `GITHUB_OAUTH` - a [GitHub personal access token](https://github.com/settings/tokens),
required for uploading to GitHub.
__release.sh__ will attempt to load environment variables from a `.env` file in
the topdir or current working directory. You can also edit __release.sh__ and
enter the tokens near the top of the file.
### Dependencies
__release.sh__ is mostly POSIX-compatible, so it should run in any Unix-like
environment provided the following are available:
- bash >= 4.3
- awk
- sed
- curl
- zip
- version control software as needed:
- git >= 2.13.0
- subversion >= 1.7.0
- mercurial >= 3.9.0 (pre-3.9 will have issues with [secure connections](https://www.mercurial-scm.org/wiki/SecureConnections))
- [jq](https://stedolan.github.io/jq/download/) >= 1.5 (when uploading)
- [pandoc](https://pandoc.org/installing.html) >= 1.19.2 (optional)

2647
.release/release.sh Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Version 1.1.3 - 2021-10-06
### Changed
- bumped version for all versions of WoW (Classic Era, Season of Mastery, BCC, Retail)
### Fixed
- error on missing options at first start
- updated Ace3.0 libraries for latest Shadowlands patch
## Version 1.1.2 - 2021-05-23
### Changed
- adopted to BigWigs release script to better support different game packages
## Version 1.1.1 - 2021-04-22
### Changed
- bumped versions for WoW Classic and Shadowlands
## Version 1.1.0 - 2020-12-08
### Added
- split of messages preserves item links, textures, substitutions and raid target markers
- added safety measures to prevent endless replacement loops
### Changed
- bumped version for Shadowlands
- bumped version for Naxxramas
### Fixed
- split of messages with excessive length no longer causes errors or broken texts
- proper handling of umlauts
## Version 1.0.1 - 2020-10-17
### Changed
- bumped version for Shadowlands Pre-Patch
## Version 1.0.0 - 2020-09-01 [First Release] ## Version 1.0.0 - 2020-09-01 [First Release]
### Added ### Added
- info section with contact and thanks - info section with contact and thanks
@@ -33,7 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- stop replacements per mapping - stop replacements per mapping
- more ooc recognition patterns - more ooc recognition patterns
### Fixed ### Fixed
- keep cases of over-long replacements - keep cases of replacements with excessive length
## Version 0.8.0-beta - 2020-06-14 [Feature Complete] ## Version 0.8.0-beta - 2020-06-14 [Feature Complete]
### Added ### Added

View File

@@ -21,8 +21,9 @@ local _G = _G
-- initialize addon -- initialize addon
local Grichelde = LibStub("AceAddon-3.0"):NewAddon(AddonTable, AddonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0") local Grichelde = LibStub("AceAddon-3.0"):NewAddon(AddonTable, AddonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
Grichelde.version = GetAddOnMetadata(AddonName, "Version") Grichelde.version = GetAddOnMetadata(AddonName, "Version")
Grichelde.build = GetAddOnMetadata(AddonName, "X-Build") or "Experimental" Grichelde.build = GetAddOnMetadata(AddonName, "X-Build") or "Development"
Grichelde.classic = _G.WOW_PROJECT_ID == _G.WOW_PROJECT_CLASSIC --Grichelde.era = _G.WOW_PROJECT_ID == _G.WOW_PROJECT_CLASSIC
--Grichelde.bcc = _G.WOW_PROJECT_ID == _G.WOW_PROJECT_BURNING_CRUSADE_CLASSIC
Grichelde.logLevel = 0 -- cannot reference Grichelde.LOG_LEVELs here as they are loaded afterwards Grichelde.logLevel = 0 -- cannot reference Grichelde.LOG_LEVELs here as they are loaded afterwards
-- publish to global env -- publish to global env

View File

@@ -1,13 +1,38 @@
## Interface: 11305 ## Interface: 11401
## Interface-Classic: 11401
## Interface-BCC: 20502
## Interface-Retail: 90100
## Title: Grichelde ## Title: Grichelde
## Notes: Replaces characters of your chat input line before sending. ## Notes: Replaces characters of your chat input line before sending.
## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile vor dem Versand. ## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile vor dem Versenden.
## Version: 1.0.0 #@debug@
## Version: 1.1.3
#@end-debug@
#@non-debug@
# ## Version: @project-version@
#@end-non-debug@
## Author: Teilzeit-Jedi ## Author: Teilzeit-Jedi
## eMail: tj@teilzeit-jedi.de ## eMail: tj@teilzeit-jedi.de
#@version-classic@
## X-Build: Classic ## X-Build: Classic
## X-Compatible: 20502
## X-Compatible: 90100
#@end-version-classic@
#@non-version-classic@
#@version-bcc@
# ## X-Build: BCC
# ## X-Compatible: 11401
# ## X-Compatible: 90100
#@end-version-bcc@
#@version-retail@
# ## X-Build: Retail
# ## X-Compatible: 11401
# ## X-Compatible: 20502
#@end-version-retail@
#@end-non-version-classic@
## X-Curse-Project-ID: 385480 ## X-Curse-Project-ID: 385480
## X-License: GPLv3 ## X-License: GPLv3
## X-Category: Chat/Communication ## X-Category: Chat/Communication
@@ -17,7 +42,21 @@
## OptionalDeps: LibStub, CallbackHandler, Ace3, LibDataBroker, LibDBIcon ## OptionalDeps: LibStub, CallbackHandler, Ace3, LibDataBroker, LibDBIcon
## SavedVariables: GricheldeDB ## SavedVariables: GricheldeDB
libs.xml #@no-lib-strip@
Libs\LibStub\LibStub.lua
Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
Libs\AceAddon-3.0\AceAddon-3.0.xml
Libs\AceLocale-3.0\AceLocale-3.0.xml
Libs\AceEvent-3.0\AceEvent-3.0.xml
Libs\AceHook-3.0\AceHook-3.0.xml
Libs\AceConsole-3.0\AceConsole-3.0.xml
Libs\AceDB-3.0\AceDB-3.0.xml
Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
Libs\AceGUI-3.0\AceGUI-3.0.xml
Libs\AceConfig-3.0\AceConfig-3.0.xml
Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
#@end-no-lib-strip@
Grichelde.lua Grichelde.lua
GricheldeConstants.lua GricheldeConstants.lua
@@ -31,4 +70,6 @@ GricheldeOptions.lua
GricheldeMinimap.lua GricheldeMinimap.lua
GricheldeChat.lua GricheldeChat.lua
#@do-not-package@
GricheldeTest.lua GricheldeTest.lua
#@end-do-not-package@

View File

@@ -2,44 +2,139 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isLetter, isUpper, isLower, toUpper, toLower, capitalize, trim, length, lengthUtf8 local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isLetter, isUpper, isLower, toUpper, toLower, capitalize, bytes2Char, trim, length, lengthUtf8
= Grichelde.F.IsAddOnLoaded, Grichelde.F.assert, Grichelde.F.nilOrEmpty, Grichelde.F.pairs, Grichelde.F.ipairs, Grichelde.F.spairs, Grichelde.F.tContains, Grichelde.F.tFilter, Grichelde.F.tInsert, Grichelde.F.tConcat, Grichelde.F.tSize, Grichelde.F.tIsEmpty, = Grichelde.F.IsAddOnLoaded, Grichelde.F.assert, Grichelde.F.nilOrEmpty, Grichelde.F.pairs, Grichelde.F.ipairs, Grichelde.F.spairs, Grichelde.F.tContains, Grichelde.F.tFilter, Grichelde.F.tInsert, Grichelde.F.tConcat, Grichelde.F.tSize, Grichelde.F.tIsEmpty,
Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isLetter, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8 Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isLetter, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.bytes2Char, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8
--- Splits a long text in longest possible chunks of <= 255 length, split at last available space --- Splits a long text in longest possible chunks of <= 255 length, split at last available space
-- @param text string -- @param text string
-- @return table -- @return array of chunks
function Grichelde:SplitText(text) function Grichelde:SplitText(text)
local chunks = {} local chunks = {}
local splitText = text local leftGuillemet = bytes2Char(194, 171) .. " "
local textSize = length(splitText or "") local rightGuillemet = " " .. bytes2Char(194, 187)
local chunkSize = Grichelde.INPUT_LIMIT - length(leftGuillemet) - length(rightGuillemet)
while (textSize > 255) do local function preserveText(newText, chunk, blockText, posEnd)
local chunk = sub(splitText, 1, 255) -- link found, block completed
local remaining = "" self:TracePrint("SplitText : Found preservable text up to %s", posEnd)
local preserved = sub(newText, 1, posEnd)
-- special case: if space is the start of the next chunk, don't split this chunk if ((length(chunk) > 0) and (length(chunk .. blockText) > chunkSize)) then
if (sub(splitText, 256, 256) ~= ' ') then -- block exceeds chunk, chunkify previous blocks
-- split at last space, don't assign directly as nil might be returned self:DebugPrint("SplitText : add chunk:", chunk)
local left, right = self:SplitOnLastMatch(chunk) tInsert(chunks, chunk .. rightGuillemet)
if (left ~= nil) then chunk = leftGuillemet .. trim(blockText)
chunk = left else
chunk = chunk .. blockText
end end
if (right ~= nil) then
remaining = right if ((length(chunk) > 0) and (length(chunk .. preserved) > chunkSize)) then
-- block exceeds chunk, chunkify previous blocks
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(preserved)
else
chunk = chunk .. preserved
end
blockText = ""
newText = sub(newText, posEnd + 1)
return newText, chunk, blockText, posEnd
end
if (length(text or "") <= Grichelde.INPUT_LIMIT) then
self:DebugPrint("SplitText : no chunk:", text)
tInsert(chunks, text)
else
local lookAheads = { '|', '*', '<', '%', '{', '(', 'o' }
local newText = text or ""
local chunk, blockText = "", ""
local currentChar
local escape = 0
-- must not enforce UTF-8 support here, as the positions are used
while ((length(newText) > 0) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
escape = escape + 1
local previousChar = currentChar
local first, textAhead = getNextCharUtf8(newText)
currentChar = first
self:DebugPrint("SplitText : currentChar, escape: %s, %s", currentChar, escape)
self:TracePrint("SplitText : chunk:", chunk)
self:TracePrint("SplitText : newText:", newText)
-- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is
-- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only
-- and if if matches do full pattern matching
if (currentChar == ' ') then
self:TracePrint("SplitText : block completed")
if ((length(chunk) > 0) and (length(chunk .. blockText) > chunkSize)) then
-- block exceeds chunk, chunkify previous blocks
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(blockText)
else
chunk = chunk .. blockText
end
blockText = currentChar
newText = textAhead
elseif (tContains(lookAheads, currentChar)) then
-- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.)
-- link detection
local linkPosEnd = self:CheckForLink(newText, currentChar)
if (linkPosEnd ~= nil) then
-- link found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, linkPosEnd)
else
-- substitution detection
local substPosEnd = self:CheckForSubstitutions(newText, currentChar)
if (substPosEnd ~= nil) then
-- substitution found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, substPosEnd)
else
-- raid target marker detection
local rtmPosEnd = self:CheckForRaidTargetMarkers(newText, currentChar)
if (rtmPosEnd ~= nil) then
-- raid target marker found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, rtmPosEnd)
else
blockText = blockText .. currentChar
newText = textAhead
end
end
end
else
blockText = blockText .. currentChar
newText = textAhead
end end
end end
self:DebugPrint("SplitText : chunk:", chunk) self:TracePrint("SplitText : main loop completed")
if (length(chunk .. blockText) > 0) then
-- catchup remaining text at the end
if (length(chunk .. blockText) > chunkSize) then
-- block exceeds chunk, chunkify previous blocks
if (length(chunk) > 0) then
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(blockText)
else
chunk = chunk .. blockText
end
else
chunk = chunk .. blockText
end
self:DebugPrint("SplitText : last chunk:", chunk)
-- sub(chunk, 1, 255) can result in broken UTF8 chars and error message
tInsert(chunks, chunk) tInsert(chunks, chunk)
splitText = remaining .. sub(splitText, 256)
textSize = length(splitText)
end end
end
-- pickup remaining text < 255
self:DebugPrint("SplitText : last chunk:", splitText)
tInsert(chunks, splitText)
return chunks return chunks
end end
@@ -63,10 +158,11 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep
local ciPattern = "" local ciPattern = ""
local ignored = {'^', '$', '(', ')', '.'} local ignored = {'^', '$', '(', ')', '.'}
local quantifiers = {'*', '+', '-', '?'} local quantifiers = {'*', '+', '-', '?'}
local pos = 1
local p, patRest = getNextCharUtf8(pattern) local p, patRest = getNextCharUtf8(pattern)
local escape = 0
while (p ~= nil) do while ((p ~= nil) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
escape = escape + 1
if (tContains(ignored, p) or tContains(quantifiers, p)) then if (tContains(ignored, p) or tContains(quantifiers, p)) then
-- ignore -- ignore
ciPattern = ciPattern .. p ciPattern = ciPattern .. p
@@ -429,47 +525,43 @@ function Grichelde:ReplaceAndConsolidate(text, replacements)
return result return result
end end
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures, raid target icons, --- looks for colored items, item links or textures
--- emotes, ooc or %-substitutons and returns the end location of the match, or 0 if no pattern was found function Grichelde:CheckForLink(text, currentChar)
-- @param text string if (currentChar == "|") then
-- @param currentChar string(1) current character (first one) of the text, given for performance reasons
-- @param previousChar string(1) previous character of the text, otherwise unreachable
-- @param preserveEmotes boolean ignore replacements for emotes, for testing purposes
-- @return number
function Grichelde:CheckForPreversableText(text, currentChar, previousChar, replaceEmotes)
self:DebugPrint("CheckForPreversableText : text:", text)
local replaceEmotes = replaceEmotes or self.db.profile.channels.emote or false
-- Calling find on ever pattern might be inefficient but its way less code than marching over every character
if (currentChar == "|" ) then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.LINKS) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.LINKS) do
local pos1, pos2 = find(text, "^" .. pattern) local pos1, pos2 = find(text, "^" .. pattern)
if (pos1 == 1) and (pos2 ~= nil) then if (pos1 == 1) and (pos2 ~= nil) then
self:DebugPrint("CheckForPreversableText : Found link or texture pattern \"%s\" at (%d, %d)", pattern, pos1, pos2) local match = sub(text, pos1, pos2)
self:DebugPrint("CheckForLink : Found link or texture pattern \"%s\" at (%d, %d)", pattern, pos1, pos2)
return pos2 return pos2
end end
end end
end end
return nil
end
-- emote detection --- looks for emotes
function Grichelde:CheckForEmote(text, currentChar, replaceEmotes)
if (currentChar == "*" or currentChar == "<") then if (currentChar == "*" or currentChar == "<") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.EMOTES) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.EMOTES) do
local pos1, pos2 = find(text, "^" .. pattern) local pos1, pos2 = find(text, "^" .. pattern)
if (pos1 == 1) and (pos2 ~= nil) then if (pos1 == 1) and (pos2 ~= nil) then
local emote = sub(text, pos1, pos2) local emote = sub(text, pos1, pos2)
if (not replaceEmotes) then if (not replaceEmotes) then
self:DebugPrint("CheckForPreversableText : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2) self:DebugPrint("CheckForEmote : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2)
return pos2 return pos2
else else
self:DebugPrint("CheckForPreversableText : ignoring emote \"%s\" at (%d, %d)", emote, pos1, pos2) self:DebugPrint("CheckForEmote : Processing emote \"%s\" at (%d, %d)", emote, pos1, pos2)
end end
end end
end end
end end
return nil
end
--- looks for %-substitutions
function Grichelde:CheckForSubstitutions(text, currentChar)
local lowerText = toLower(text) local lowerText = toLower(text)
-- %-substitutions
if (currentChar == "%") then if (currentChar == "%") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.SUBSTITUTES) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.SUBSTITUTES) do
local pos1, pos2 = find(lowerText, "^" .. pattern) local pos1, pos2 = find(lowerText, "^" .. pattern)
@@ -479,8 +571,12 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- raid target markers --- looks for general and localized raid target markers
function Grichelde:CheckForRaidTargetMarkers(text, currentChar)
local lowerText = toLower(text)
if (currentChar == "{") then if (currentChar == "{") then
-- rt1-9 -- rt1-9
local pattern = Grichelde.IGNORE_PATTERNS.RAID_TARGETS[1] local pattern = Grichelde.IGNORE_PATTERNS.RAID_TARGETS[1]
@@ -501,8 +597,12 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- ooc bracket detection --- looks for ooc with brackets
function Grichelde:CheckForOocBrackets(text, currentChar)
local lowerText = toLower(text)
if (currentChar == "(") then if (currentChar == "(") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.OOC_BRACKETS) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.OOC_BRACKETS) do
local pos1, pos2 = find(lowerText, "^" .. pattern) local pos1, pos2 = find(lowerText, "^" .. pattern)
@@ -512,15 +612,63 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- ooc without brackets: remaing text is treated as ooc completely! --- looks for ooc without brackets
function Grichelde:CheckForOocNoBrackets(text, currentChar, previousChar)
local lowerText = toLower(text)
if (currentChar == "o") then if (currentChar == "o") then
local pattern = Grichelde.IGNORE_PATTERNS.OOC_NO_BRACKETS[1] local pattern = Grichelde.IGNORE_PATTERNS.OOC_NO_BRACKETS[1]
if ((previousChar == nil) or (find(previousChar, "%s") ~= nil)) and (find(lowerText, pattern) ~= nil) then if ((previousChar == nil) or (find(previousChar, "%s") ~= nil)) and (find(lowerText, pattern) ~= nil) then
self:DebugPrint("CheckForPreversableText : ooc for remaing text") self:DebugPrint("CheckForPreversableText : ooc for remaing text")
-- remaing text is treated as ooc completely!
return length(text) return length(text)
end end
end end
return nil
end
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures, raid target icons,
--- emotes, ooc or %-substitutons and returns the end location of the match, or 0 if no pattern was found
-- @param text string
-- @param currentChar string(1) current character (first one) of the text, given for performance reasons
-- @param previousChar string(1) previous character of the text, otherwise unreachable
-- @param preserveEmotes boolean ignore replacements for emotes, for testing purposes
-- @return number
function Grichelde:CheckForPreversableText(text, currentChar, previousChar, replaceEmotes)
self:DebugPrint("CheckForPreversableText : text:", text)
local replaceEmotes = replaceEmotes or self.db.profile.channels.emote or false
local linkPos = self:CheckForLink(text, currentChar)
if (linkPos ~= nil) then
return linkPos
end
local emotePos = self:CheckForEmote(text, currentChar, replaceEmotes)
if (emotePos ~= nil) then
return emotePos
end
local substPos = self:CheckForSubstitutions(text, currentChar)
if (substPos ~= nil) then
return substPos
end
local rtmPos = self:CheckForRaidTargetMarkers(text, currentChar)
if (rtmPos ~= nil) then
return rtmPos
end
local oocBracketPos = self:CheckForOocBrackets(text, currentChar)
if (oocBracketPos ~= nil) then
return oocBracketPos
end
local oocNoBracketPos = self:CheckForOocNoBrackets(text, currentChar, previousChar)
if (oocNoBracketPos ~= nil) then
return oocNoBracketPos
end
self:DebugPrint("CheckForPreversableText : no ignore pattern found") self:DebugPrint("CheckForPreversableText : no ignore pattern found")
return 0 return 0
@@ -536,49 +684,49 @@ function Grichelde:ReplaceText(text, replacements, replaceEmotes)
local newText = text local newText = text
local preserveEmotes = replaceEmotes or self.db.profile.channels.emote or false local preserveEmotes = replaceEmotes or self.db.profile.channels.emote or false
local replacements = replacements or self.db.profile.replacements or {} local replacements = replacements or self.db.profile.replacements or {}
local finalText = "" local finalText, replaceText = "", ""
local currentChar
local escape = 0
local currentChar, previousChar -- must not enforce UTF-8 support here, as the positions are used
local current = 1 while ((length(newText) > 0) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
local lastStart = 1 escape = escape + 1
local previousChar = currentChar
-- no UTF-8 support required here, as the positions are used local first, textAhead = getNextCharUtf8(newText)
while current <= length(newText) do currentChar = first
previousChar = currentChar self:TracePrint("ReplaceText : currentChar : %s", currentChar)
currentChar = sub(newText, current, current)
self:TracePrint("ReplaceText : current/char : %s,%s", current, currentChar)
-- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is -- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is
-- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only -- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only
-- and if if matches do full pattern matching -- and if if matches do full pattern matching
if (not tContains(lookAheads, currentChar)) then if (tContains(lookAheads, currentChar)) then
current = current + 1
else
-- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.) -- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.)
local textAhead = sub(newText, current) --local textAhead = sub(newText, current)
local posEnd = self:CheckForPreversableText(textAhead, currentChar, previousChar, preserveEmotes) local posEnd = self:CheckForPreversableText(newText, currentChar, previousChar, preserveEmotes)
if (posEnd > 0) then if (posEnd > 0) then
self:DebugPrint("ReplaceText : Found an ignore pattern") self:DebugPrint("ReplaceText : Found an ignore pattern")
-- split text and continue after preserved text -- replace all text up until now
local textBefore = sub(newText, lastStart, current - 1) local replacement = self:ReplaceAndConsolidate(replaceText, replacements)
local replacement = self:ReplaceAndConsolidate(textBefore, replacements) local preserved = sub(newText, 1, posEnd)
local preservedText = sub(textAhead, 1, posEnd)
finalText = finalText .. replacement .. preservedText finalText = finalText .. replacement .. preserved
current = current + posEnd replaceText = ""
lastStart = current newText = sub(newText, posEnd + 1)
self:DebugPrint("ReplaceText : restarting at", lastStart) self:DebugPrint("ReplaceText : remaining text", newText)
else else
-- no corresponding end was found to start pattern, continue loop with next char -- no corresponding end was found to start pattern, continue loop with next char
current = current + 1 replaceText = replaceText .. currentChar
newText = textAhead
end end
else
replaceText = replaceText .. currentChar
newText = textAhead
end end
end end
-- catchup remaining text to the end -- catchup remaining text to the end
local remainingText = sub(newText, lastStart) local replacement = self:ReplaceAndConsolidate(replaceText, replacements)
local replacement = self:ReplaceAndConsolidate(remainingText, replacements)
finalText = finalText .. replacement finalText = finalText .. replacement
self:DebugPrint("ReplaceText : replaced \"%s\"", text) self:DebugPrint("ReplaceText : replaced \"%s\"", text)
@@ -592,22 +740,24 @@ function Grichelde:IsOneBigEmote(text)
-- emote detection -- emote detection
local isEmote = false local isEmote = false
-- scheme *emote* local firstChar, rest = getNextCharUtf8(firstWord)
if (sub(firstWord, 1, 1) == "<") then
-- scheme <emote>
if (firstChar == "<") then
-- search for emote end -- search for emote end
local _, emoteEnd = find(text, "%>", 2) local _, emoteEnd = find(text, "%>", 2)
isEmote = (emoteEnd == length(text)) isEmote = (emoteEnd == lengthUtf8(text))
end
if (not isEmote and (sub(firstWord, 1, 1) == "*")) then
-- search for emote end
local _, emoteEnd = find(text, "%*", 2)
isEmote = (emoteEnd == length(text))
end end
if (not isEmote and (firstChar == "*")) then
if (getNextCharUtf8(rest) == "*") then
-- scheme **emote** -- scheme **emote**
if (not isEmote and (sub(firstWord, 1, 2) == "**")) then
-- search for emote end
local _, emoteEnd = find(text, "%*%*", 3) local _, emoteEnd = find(text, "%*%*", 3)
isEmote = (emoteEnd == length(text)) isEmote = (emoteEnd == lengthUtf8(text))
else
-- scheme *emote*
local _, emoteEnd = find(text, "%*", 2)
isEmote = (emoteEnd == lengthUtf8(text))
end
end end
-- the whole text is one big emote -- the whole text is one big emote
@@ -659,7 +809,7 @@ function Grichelde:CheckReplacementAllowed(text, channel)
assert(firstWord ~= nil, "firstWord is never nil") assert(firstWord ~= nil, "firstWord is never nil")
-- don't replace slash commands -- don't replace slash commands
if (sub(firstWord, 1, 1) == "/") then if (getNextCharUtf8(firstWord) == "/") then
self:DebugPrint("CheckReplacementAllowed : skip other slash commands:", firstWord) self:DebugPrint("CheckReplacementAllowed : skip other slash commands:", firstWord)
return false return false
end end
@@ -691,7 +841,7 @@ function Grichelde:CheckAndExtractMessageTypeTarget(message)
end end
-- first word should be a chat command -- first word should be a chat command
if (sub(message, 1, 1) == "/") then if (getNextCharUtf8(message) == "/") then
-- extract chat command -- extract chat command
local chatCmd, targetAndText = self:SplitOnFirstMatch(message) local chatCmd, targetAndText = self:SplitOnFirstMatch(message)
assert(chatCmd ~= nil, "chatCmd is never nil") assert(chatCmd ~= nil, "chatCmd is never nil")

View File

@@ -5,6 +5,8 @@ local Grichelde = _G.Grichelde or {}
-- constants and upvalues -- constants and upvalues
Grichelde.LOG_LEVEL = { DEBUG = 1, TRACE = 2 } Grichelde.LOG_LEVEL = { DEBUG = 1, TRACE = 2 }
Grichelde.INPUT_LIMIT = 255
Grichelde.ENDLESS_LOOP_LIMIT = 10000
Grichelde.MAPPING_OFFSET = 10 Grichelde.MAPPING_OFFSET = 10
Grichelde.MINIMAP_ENABLED = 1.0 Grichelde.MINIMAP_ENABLED = 1.0
Grichelde.MINIMAP_DARKENDED = 0.5 Grichelde.MINIMAP_DARKENDED = 0.5
@@ -116,6 +118,7 @@ Grichelde.BLIZZ_TYPE_TO_OPTIONS = {
} }
-- do not replace these patterns -- do not replace these patterns
-- combined item links in the chat will look like this: |cff9d9d9d|Hitem:3299::::::::20:257::::::|h[Fractured Canine]|h|r
Grichelde.IGNORE_PATTERNS = { Grichelde.IGNORE_PATTERNS = {
LINKS = { LINKS = {
"|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links) "|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links)

View File

@@ -254,7 +254,7 @@ function Grichelde:CreateOptionsUI()
name = self.L.Options_Help_Examples_Import_Name, name = self.L.Options_Help_Examples_Import_Name,
-- desc = self.L.Options_Help_Examples_Import_Desc, -- desc = self.L.Options_Help_Examples_Import_Desc,
desc = function() return format(self.L.Options_Help_Examples_Import_Desc, cPrefix(self.L.Options_Help_Examples[selectedExample].name)) end, desc = function() return format(self.L.Options_Help_Examples_Import_Desc, cPrefix(self.L.Options_Help_Examples[selectedExample].name)) end,
func = function(info) self:ImportExample(selectedExample) end, func = function(_) self:ImportExample(selectedExample) end,
}, },
spacer4 = { spacer4 = {
@@ -617,6 +617,7 @@ function Grichelde:RefreshOptions(replacementsTable)
self:TracePrint("RefreshOptions : DB table:") self:TracePrint("RefreshOptions : DB table:")
self:TracePrint(replacementsTable) self:TracePrint(replacementsTable)
if (self.options ~= nil) then
-- remove all previous replacements from options (not DB), except header and buttons -- remove all previous replacements from options (not DB), except header and buttons
local replacements = self.options.args.replacements.args or {} local replacements = self.options.args.replacements.args or {}
for k, _ in pairs(replacements) do for k, _ in pairs(replacements) do
@@ -629,13 +630,16 @@ function Grichelde:RefreshOptions(replacementsTable)
local _, replNumber = self:SplitOnFirstMatch(replName, "_") local _, replNumber = self:SplitOnFirstMatch(replName, "_")
replacements[replName] = self:CreateMapping(toNumber(replNumber)) replacements[replName] = self:CreateMapping(toNumber(replNumber))
end end
end
-- self:TracePrint("RefreshOptions : UI options:") -- self:TracePrint("RefreshOptions : UI options:")
-- self:TracePrint(replacements) -- self:TracePrint(replacements)
end end
function Grichelde:RefreshDialog() function Grichelde:RefreshDialog()
if (self.dialog ~= nil) then
self.dialog:ConfigTableChanged(nil, self.name) self.dialog:ConfigTableChanged(nil, self.name)
end
end end
function Grichelde:AddEmptyMapping() function Grichelde:AddEmptyMapping()

View File

@@ -84,12 +84,6 @@ function Grichelde:SplitOnLastMatch(text, delimPattern, start)
return left, right or text return left, right or text
end end
--- Splits at last word of a text line
function Grichelde:TestMatch(text, pattern)
local pos1, pos2, left, right = find(text, pattern, 1)
self:DebugPrint("TestMatch : pos1: %d, pos2: %d, left: %s, right: %s", pos1, pos2, left, right)
end
function Grichelde:Format(message, ...) function Grichelde:Format(message, ...)
if (message == nil) then if (message == nil) then
return "<nil>" return "<nil>"

View File

@@ -28,9 +28,9 @@
-- end -- end
-- @class file -- @class file
-- @name AceAddon-3.0.lua -- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $ -- @release $Id: AceAddon-3.0.lua 1238 2020-08-28 16:18:42Z nevcairiel $
local MAJOR, MINOR = "AceAddon-3.0", 12 local MAJOR, MINOR = "AceAddon-3.0", 13
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR) local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceAddon then return end -- No Upgrade needed. if not AceAddon then return end -- No Upgrade needed.
@@ -601,10 +601,20 @@ function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
-- Blizzard AddOns which can load very early in the loading process and mess with Ace3 addon loading
local BlizzardEarlyLoadAddons = {
Blizzard_DebugTools = true,
Blizzard_TimeManager = true,
Blizzard_BattlefieldMap = true,
Blizzard_MapCanvas = true,
Blizzard_SharedMapDataProviders = true,
Blizzard_CombatLog = true,
}
-- Event Handling -- Event Handling
local function onEvent(this, event, arg1) local function onEvent(this, event, arg1)
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up -- 2020-08-28 nevcairiel - ignore the load event of Blizzard addons which occur early in the loading process
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then if (event == "ADDON_LOADED" and (arg1 == nil or not BlizzardEarlyLoadAddons[arg1])) or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration -- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1) local addon = tremove(AceAddon.initializequeue, 1)

View File

@@ -3,7 +3,7 @@
-- as well as associate it with a slash command. -- as well as associate it with a slash command.
-- @class file -- @class file
-- @name AceConfig-3.0 -- @name AceConfig-3.0
-- @release $Id: AceConfig-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $ -- @release $Id: AceConfig-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
--[[ --[[
AceConfig-3.0 AceConfig-3.0

View File

@@ -1,7 +1,7 @@
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames. --- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
-- @class file -- @class file
-- @name AceConfigCmd-3.0 -- @name AceConfigCmd-3.0
-- @release $Id: AceConfigCmd-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $ -- @release $Id: AceConfigCmd-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
--[[ --[[
AceConfigCmd-3.0 AceConfigCmd-3.0

View File

@@ -1,13 +1,13 @@
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables. --- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
-- @class file -- @class file
-- @name AceConfigDialog-3.0 -- @name AceConfigDialog-3.0
-- @release $Id: AceConfigDialog-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $ -- @release $Id: AceConfigDialog-3.0.lua 1248 2021-02-05 14:27:49Z funkehdude $
local LibStub = LibStub local LibStub = LibStub
local gui = LibStub("AceGUI-3.0") local gui = LibStub("AceGUI-3.0")
local reg = LibStub("AceConfigRegistry-3.0") local reg = LibStub("AceConfigRegistry-3.0")
local MAJOR, MINOR = "AceConfigDialog-3.0", 66 local MAJOR, MINOR = "AceConfigDialog-3.0", 81
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR) local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigDialog then return end if not AceConfigDialog then return end
@@ -15,22 +15,23 @@ if not AceConfigDialog then return end
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {} AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
AceConfigDialog.Status = AceConfigDialog.Status or {} AceConfigDialog.Status = AceConfigDialog.Status or {}
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame") AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
AceConfigDialog.tooltip = AceConfigDialog.tooltip or CreateFrame("GameTooltip", "AceConfigDialogTooltip", UIParent, "GameTooltipTemplate")
AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {} AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {} AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {} AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
-- Lua APIs -- Lua APIs
local tconcat, tinsert, tsort, tremove, tsort = table.concat, table.insert, table.sort, table.remove, table.sort local tinsert, tsort, tremove, wipe = table.insert, table.sort, table.remove, table.wipe
local strmatch, format = string.match, string.format local strmatch, format = string.match, string.format
local assert, loadstring, error = assert, loadstring, error local error = error
local pairs, next, select, type, unpack, wipe, ipairs = pairs, next, select, type, unpack, wipe, ipairs local pairs, next, select, type, unpack, ipairs = pairs, next, select, type, unpack, ipairs
local rawset, tostring, tonumber = rawset, tostring, tonumber local tostring, tonumber = tostring, tonumber
local math_min, math_max, math_floor = math.min, math.max, math.floor local math_min, math_max, math_floor = math.min, math.max, math.floor
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script -- List them here for Mikk's FindGlobals script
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show -- GLOBALS: NORMAL_FONT_COLOR, ACCEPT, CANCEL
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge -- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler -- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
@@ -45,39 +46,10 @@ local function errorhandler(err)
return geterrorhandler()(err) return geterrorhandler()(err)
end end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...) local function safecall(func, ...)
return Dispatchers[select("#", ...)](func, ...) if func then
return xpcall(func, errorhandler, ...)
end
end end
local width_multiplier = 170 local width_multiplier = 170
@@ -325,7 +297,7 @@ local function compareOptions(a,b)
return NameA:upper() < NameB:upper() return NameA:upper() < NameB:upper()
end end
if OrderA < 0 then if OrderA < 0 then
if OrderB > 0 then if OrderB >= 0 then
return false return false
end end
else else
@@ -533,8 +505,9 @@ local function OptionOnMouseOver(widget, event)
local options = user.options local options = user.options
local path = user.path local path = user.path
local appName = user.appName local appName = user.appName
local tooltip = AceConfigDialog.tooltip
GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT") tooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
local name = GetOptionsMemberValue("name", opt, options, path, appName) local name = GetOptionsMemberValue("name", opt, options, path, appName)
local desc = GetOptionsMemberValue("desc", opt, options, path, appName) local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
local usage = GetOptionsMemberValue("usage", opt, options, path, appName) local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
@@ -542,23 +515,23 @@ local function OptionOnMouseOver(widget, event)
if descStyle and descStyle ~= "tooltip" then return end if descStyle and descStyle ~= "tooltip" then return end
GameTooltip:SetText(name, 1, .82, 0, true) tooltip:SetText(name, 1, .82, 0, true)
if opt.type == "multiselect" then if opt.type == "multiselect" then
GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, true) tooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
end end
if type(desc) == "string" then if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, true) tooltip:AddLine(desc, 1, 1, 1, true)
end end
if type(usage) == "string" then if type(usage) == "string" then
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true) tooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
end end
GameTooltip:Show() tooltip:Show()
end end
local function OptionOnMouseLeave(widget, event) local function OptionOnMouseLeave(widget, event)
GameTooltip:Hide() AceConfigDialog.tooltip:Hide()
end end
local function GetFuncName(option) local function GetFuncName(option)
@@ -569,71 +542,127 @@ local function GetFuncName(option)
return "set" return "set"
end end
end end
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...) do
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then local frame = AceConfigDialog.popup
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {} if not frame or oldminor < 81 then
frame = CreateFrame("Frame", nil, UIParent)
AceConfigDialog.popup = frame
frame:Hide()
frame:SetPoint("CENTER", UIParent, "CENTER")
frame:SetSize(320, 72)
frame:EnableMouse(true) -- Do not allow click-through on the frame
frame:SetFrameStrata("TOOLTIP")
frame:SetFrameLevel(100) -- Lots of room to draw under it
frame:SetScript("OnKeyDown", function(self, key)
if key == "ESCAPE" then
self:SetPropagateKeyboardInput(false)
if self.cancel:IsShown() then
self.cancel:Click()
else -- Showing a validation error
self:Hide()
end end
local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] else
for k in pairs(t) do self:SetPropagateKeyboardInput(true)
t[k] = nil
end end
t.text = message end)
t.button1 = ACCEPT
t.button2 = CANCEL
t.preferredIndex = STATICPOPUP_NUMDIALOGS
local dialog, oldstrata
t.OnAccept = function()
safecall(func, unpack(t))
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
del(info)
end
t.OnCancel = function()
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
del(info)
end
for i = 1, select("#", ...) do
t[i] = select(i, ...) or false
end
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG") if not frame.SetFixedFrameStrata then -- API capability check (classic check)
if dialog then frame:SetBackdrop({
oldstrata = dialog:GetFrameStrata() bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
dialog:SetFrameStrata("TOOLTIP") edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]],
tile = true,
tileSize = 32,
edgeSize = 32,
insets = { left = 11, right = 11, top = 11, bottom = 11 },
})
else
local border = CreateFrame("Frame", nil, frame, "DialogBorderOpaqueTemplate")
border:SetAllPoints(frame)
frame:SetFixedFrameStrata(true)
frame:SetFixedFrameLevel(true)
end end
local text = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
text:SetSize(290, 0)
text:SetPoint("TOP", 0, -16)
frame.text = text
local function newButton(text)
local button = CreateFrame("Button", nil, frame)
button:SetSize(128, 21)
button:SetNormalFontObject(GameFontNormal)
button:SetHighlightFontObject(GameFontHighlight)
button:SetNormalTexture(130763) -- "Interface\\Buttons\\UI-DialogBox-Button-Up"
button:GetNormalTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetPushedTexture(130761) -- "Interface\\Buttons\\UI-DialogBox-Button-Down"
button:GetPushedTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetHighlightTexture(130762) -- "Interface\\Buttons\\UI-DialogBox-Button-Highlight"
button:GetHighlightTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetText(text)
return button
end
local accept = newButton(ACCEPT)
accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
frame.accept = accept
local cancel = newButton(CANCEL)
cancel:SetPoint("LEFT", accept, "RIGHT", 13, 0)
frame.cancel = cancel
end
end
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
local frame = AceConfigDialog.popup
frame:Show()
frame.text:SetText(message)
-- From StaticPopup.lua
-- local height = 32 + text:GetHeight() + 2;
-- height = height + 6 + accept:GetHeight()
-- We add 32 + 2 + 6 + 21 (button height) == 61
local height = 61 + frame.text:GetHeight()
frame:SetHeight(height)
frame.accept:ClearAllPoints()
frame.accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
frame.cancel:Show()
local t = {...}
local tCount = select("#", ...)
frame.accept:SetScript("OnClick", function(self)
safecall(func, unpack(t, 1, tCount)) -- Manually set count as unpack() stops on nil (bug with #table)
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
frame:Hide()
self:SetScript("OnClick", nil)
frame.cancel:SetScript("OnClick", nil)
del(info)
end)
frame.cancel:SetScript("OnClick", function(self)
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
frame:Hide()
self:SetScript("OnClick", nil)
frame.accept:SetScript("OnClick", nil)
del(info)
end)
end end
local function validationErrorPopup(message) local function validationErrorPopup(message)
if not StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] then local frame = AceConfigDialog.popup
StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] = {} frame:Show()
end frame.text:SetText(message)
local t = StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] -- From StaticPopup.lua
t.text = message -- local height = 32 + text:GetHeight() + 2;
t.button1 = OKAY -- height = height + 6 + accept:GetHeight()
t.preferredIndex = STATICPOPUP_NUMDIALOGS -- We add 32 + 2 + 6 + 21 (button height) == 61
local dialog, oldstrata local height = 61 + frame.text:GetHeight()
t.OnAccept = function() frame:SetHeight(height)
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
end
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
dialog = StaticPopup_Show("ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG") frame.accept:ClearAllPoints()
if dialog then frame.accept:SetPoint("BOTTOM", frame, "BOTTOM", 0, 16)
oldstrata = dialog:GetFrameStrata() frame.cancel:Hide()
dialog:SetFrameStrata("TOOLTIP")
end frame.accept:SetScript("OnClick", function()
frame:Hide()
end)
end end
local function ActivateControl(widget, event, ...) local function ActivateControl(widget, event, ...)
@@ -886,7 +915,7 @@ end
local function MultiControlOnClosed(widget, event, ...) local function MultiControlOnClosed(widget, event, ...)
local user = widget:GetUserDataTable() local user = widget:GetUserDataTable()
if user.valuechanged then if user.valuechanged and not widget:IsReleasing() then
local iscustom = user.rootframe:GetUserData("iscustom") local iscustom = user.rootframe:GetUserData("iscustom")
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
if iscustom then if iscustom then
@@ -1064,6 +1093,23 @@ local function InjectInfo(control, options, option, path, rootframe, appName)
control:SetCallback("OnEnter", OptionOnMouseOver) control:SetCallback("OnEnter", OptionOnMouseOver)
end end
local function CreateControl(userControlType, fallbackControlType)
local control
if userControlType then
control = gui:Create(userControlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(userControlType)))
end
end
if not control then
control = gui:Create(fallbackControlType)
end
return control
end
local function sortTblAsStrings(x,y)
return tostring(x) < tostring(y) -- Support numbers as keys
end
--[[ --[[
options - root of the options table being fed options - root of the options table being fed
@@ -1112,8 +1158,9 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName) local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName) local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
if type(image) == "string" or type(image) == "number" then local iconControl = type(image) == "string" or type(image) == "number"
control = gui:Create("Icon") control = CreateControl(v.dialogControl or v.control, iconControl and "Icon" or "Button")
if iconControl then
if not width then if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName) width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end end
@@ -1134,18 +1181,12 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetImageSize(width, height) control:SetImageSize(width, height)
control:SetLabel(name) control:SetLabel(name)
else else
control = gui:Create("Button")
control:SetText(name) control:SetText(name)
end end
control:SetCallback("OnClick",ActivateControl) control:SetCallback("OnClick",ActivateControl)
elseif v.type == "input" then elseif v.type == "input" then
local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox" control = CreateControl(v.dialogControl or v.control, v.multiline and "MultiLineEditBox" or "EditBox")
control = gui:Create(controlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox")
end
if v.multiline and control.SetNumLines then if v.multiline and control.SetNumLines then
control:SetNumLines(tonumber(v.multiline) or 4) control:SetNumLines(tonumber(v.multiline) or 4)
@@ -1159,7 +1200,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetText(text) control:SetText(text)
elseif v.type == "toggle" then elseif v.type == "toggle" then
control = gui:Create("CheckBox") control = CreateControl(v.dialogControl or v.control, "CheckBox")
control:SetLabel(name) control:SetLabel(name)
control:SetTriState(v.tristate) control:SetTriState(v.tristate)
local value = GetOptionsMemberValue("get",v, options, path, appName) local value = GetOptionsMemberValue("get",v, options, path, appName)
@@ -1182,7 +1223,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end end
end end
elseif v.type == "range" then elseif v.type == "range" then
control = gui:Create("Slider") control = CreateControl(v.dialogControl or v.control, "Slider")
control:SetLabel(name) control:SetLabel(name)
control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0) control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0)
control:SetIsPercent(v.isPercent) control:SetIsPercent(v.isPercent)
@@ -1196,6 +1237,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
elseif v.type == "select" then elseif v.type == "select" then
local values = GetOptionsMemberValue("values", v, options, path, appName) local values = GetOptionsMemberValue("values", v, options, path, appName)
local sorting = GetOptionsMemberValue("sorting", v, options, path, appName)
if v.style == "radio" then if v.style == "radio" then
local disabled = CheckOptionDisabled(v, options, path, appName) local disabled = CheckOptionDisabled(v, options, path, appName)
local width = GetOptionsMemberValue("width",v,options,path,appName) local width = GetOptionsMemberValue("width",v,options,path,appName)
@@ -1206,12 +1248,14 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:PauseLayout() control:PauseLayout()
local optionValue = GetOptionsMemberValue("get",v, options, path, appName) local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
local t = {} if not sorting then
sorting = {}
for value, text in pairs(values) do for value, text in pairs(values) do
t[#t+1]=value sorting[#sorting+1]=value
end end
tsort(t) tsort(sorting, sortTblAsStrings)
for k, value in ipairs(t) do end
for k, value in ipairs(sorting) do
local text = values[value] local text = values[value]
local radio = gui:Create("CheckBox") local radio = gui:Create("CheckBox")
radio:SetLabel(text) radio:SetLabel(text)
@@ -1238,19 +1282,14 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:ResumeLayout() control:ResumeLayout()
control:DoLayout() control:DoLayout()
else else
local controlType = v.dialogControl or v.control or "Dropdown" control = CreateControl(v.dialogControl or v.control, "Dropdown")
control = gui:Create(controlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
control = gui:Create("Dropdown")
end
local itemType = v.itemControl local itemType = v.itemControl
if itemType and not gui:GetWidgetVersion(itemType) then if itemType and not gui:GetWidgetVersion(itemType) then
geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType))) geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType)))
itemType = nil itemType = nil
end end
control:SetLabel(name) control:SetLabel(name)
control:SetList(values, nil, itemType) control:SetList(values, sorting, itemType)
local value = GetOptionsMemberValue("get",v, options, path, appName) local value = GetOptionsMemberValue("get",v, options, path, appName)
if not values[value] then if not values[value] then
value = nil value = nil
@@ -1263,8 +1302,6 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
local values = GetOptionsMemberValue("values", v, options, path, appName) local values = GetOptionsMemberValue("values", v, options, path, appName)
local disabled = CheckOptionDisabled(v, options, path, appName) local disabled = CheckOptionDisabled(v, options, path, appName)
local controlType = v.dialogControl or v.control
local valuesort = new() local valuesort = new()
if values then if values then
for value, text in pairs(values) do for value, text in pairs(values) do
@@ -1273,6 +1310,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end end
tsort(valuesort) tsort(valuesort)
local controlType = v.dialogControl or v.control
if controlType then if controlType then
control = gui:Create(controlType) control = gui:Create(controlType)
if not control then if not control then
@@ -1346,7 +1384,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
del(valuesort) del(valuesort)
elseif v.type == "color" then elseif v.type == "color" then
control = gui:Create("ColorPicker") control = CreateControl(v.dialogControl or v.control, "ColorPicker")
control:SetLabel(name) control:SetLabel(name)
control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName)) control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName)) control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
@@ -1354,18 +1392,18 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetCallback("OnValueConfirmed",ActivateControl) control:SetCallback("OnValueConfirmed",ActivateControl)
elseif v.type == "keybinding" then elseif v.type == "keybinding" then
control = gui:Create("Keybinding") control = CreateControl(v.dialogControl or v.control, "Keybinding")
control:SetLabel(name) control:SetLabel(name)
control:SetKey(GetOptionsMemberValue("get",v, options, path, appName)) control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnKeyChanged",ActivateControl) control:SetCallback("OnKeyChanged",ActivateControl)
elseif v.type == "header" then elseif v.type == "header" then
control = gui:Create("Heading") control = CreateControl(v.dialogControl or v.control, "Heading")
control:SetText(name) control:SetText(name)
control.width = "fill" control.width = "fill"
elseif v.type == "description" then elseif v.type == "description" then
control = gui:Create("Label") control = CreateControl(v.dialogControl or v.control, "Label")
control:SetText(name) control:SetText(name)
local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName) local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
@@ -1453,6 +1491,7 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
local option = user.option local option = user.option
local path = user.path local path = user.path
local appName = user.appName local appName = user.appName
local tooltip = AceConfigDialog.tooltip
local feedpath = new() local feedpath = new()
for i = 1, #path do for i = 1, #path do
@@ -1469,24 +1508,25 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
local name = GetOptionsMemberValue("name", group, options, feedpath, appName) local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName) local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
GameTooltip:SetOwner(button, "ANCHOR_NONE") tooltip:SetOwner(button, "ANCHOR_NONE")
tooltip:ClearAllPoints()
if widget.type == "TabGroup" then if widget.type == "TabGroup" then
GameTooltip:SetPoint("BOTTOM",button,"TOP") tooltip:SetPoint("BOTTOM",button,"TOP")
else else
GameTooltip:SetPoint("LEFT",button,"RIGHT") tooltip:SetPoint("LEFT",button,"RIGHT")
end end
GameTooltip:SetText(name, 1, .82, 0, true) tooltip:SetText(name, 1, .82, 0, true)
if type(desc) == "string" then if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, true) tooltip:AddLine(desc, 1, 1, 1, true)
end end
GameTooltip:Show() tooltip:Show()
end end
local function TreeOnButtonLeave(widget, event, value, button) local function TreeOnButtonLeave(widget, event, value, button)
GameTooltip:Hide() AceConfigDialog.tooltip:Hide()
end end
@@ -1533,10 +1573,6 @@ local function GroupSelected(widget, event, uniquevalue)
end end
BuildPath(feedpath, ("\001"):split(uniquevalue)) BuildPath(feedpath, ("\001"):split(uniquevalue))
local group = options
for i = 1, #feedpath do
group = GetSubOption(group, feedpath[i])
end
widget:ReleaseChildren() widget:ReleaseChildren()
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath) AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)

View File

@@ -8,10 +8,10 @@
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName". -- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
-- @class file -- @class file
-- @name AceConfigRegistry-3.0 -- @name AceConfigRegistry-3.0
-- @release $Id: AceConfigRegistry-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $ -- @release $Id: AceConfigRegistry-3.0.lua 1207 2019-06-23 12:08:33Z nevcairiel $
local CallbackHandler = LibStub("CallbackHandler-1.0") local CallbackHandler = LibStub("CallbackHandler-1.0")
local MAJOR, MINOR = "AceConfigRegistry-3.0", 18 local MAJOR, MINOR = "AceConfigRegistry-3.0", 20
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR) local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigRegistry then return end if not AceConfigRegistry then return end
@@ -59,7 +59,6 @@ local optstring={["nil"]=true,["string"]=true, _="string"}
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"} local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
local optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number or funcref"} local optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"} local optnumber={["nil"]=true,["number"]=true, _="number"}
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"} local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"} local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"} local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
@@ -95,13 +94,20 @@ local basekeys={
} }
local typedkeys={ local typedkeys={
header={}, header={
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
description={ description={
image=optstringnumberfunc, image=optstringnumberfunc,
imageCoords=optmethodtable, imageCoords=optmethodtable,
imageHeight=optnumber, imageHeight=optnumber,
imageWidth=optnumber, imageWidth=optnumber,
fontSize=optstringfunc, fontSize=optstringfunc,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
group={ group={
args=istable, args=istable,
@@ -118,6 +124,9 @@ local typedkeys={
imageCoords=optmethodtable, imageCoords=optmethodtable,
imageHeight=optnumber, imageHeight=optnumber,
imageWidth=optnumber, imageWidth=optnumber,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
input={ input={
pattern=optstring, pattern=optstring,
@@ -131,6 +140,9 @@ local typedkeys={
tristate=optbool, tristate=optbool,
image=optstringnumberfunc, image=optstringnumberfunc,
imageCoords=optmethodtable, imageCoords=optmethodtable,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
tristate={ tristate={
}, },
@@ -142,9 +154,13 @@ local typedkeys={
step=optnumber, step=optnumber,
bigStep=optnumber, bigStep=optnumber,
isPercent=optbool, isPercent=optbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
select={ select={
values=ismethodtable, values=ismethodtable,
sorting=optmethodtable,
style={ style={
["nil"]=true, ["nil"]=true,
["string"]={dropdown=true,radio=true}, ["string"]={dropdown=true,radio=true},
@@ -165,9 +181,14 @@ local typedkeys={
}, },
color={ color={
hasAlpha=optmethodbool, hasAlpha=optmethodbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
keybinding={ keybinding={
-- TODO control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
}, },
} }

View File

@@ -40,15 +40,15 @@
-- end -- end
-- @class file -- @class file
-- @name AceDB-3.0.lua -- @name AceDB-3.0.lua
-- @release $Id: AceDB-3.0.lua 1142 2016-07-11 08:36:19Z nevcairiel $ -- @release $Id: AceDB-3.0.lua 1217 2019-07-11 03:06:18Z funkydude $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 26 local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 27
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR) local AceDB = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
if not AceDB then return end -- No upgrade needed if not AceDB then return end -- No upgrade needed
-- Lua APIs -- Lua APIs
local type, pairs, next, error = type, pairs, next, error local type, pairs, next, error = type, pairs, next, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget local setmetatable, rawset, rawget = setmetatable, rawset, rawget
-- WoW APIs -- WoW APIs
local _G = _G local _G = _G
@@ -397,7 +397,7 @@ AceDB.frame:SetScript("OnEvent", logoutHandler)
-- @param defaults A table of defaults for this database -- @param defaults A table of defaults for this database
function DBObjectLib:RegisterDefaults(defaults) function DBObjectLib:RegisterDefaults(defaults)
if defaults and type(defaults) ~= "table" then if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2) error(("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
end end
validateDefaults(defaults, self.keys) validateDefaults(defaults, self.keys)
@@ -429,7 +429,7 @@ end
-- @param name The name of the profile to set as the current profile -- @param name The name of the profile to set as the current profile
function DBObjectLib:SetProfile(name) function DBObjectLib:SetProfile(name)
if type(name) ~= "string" then if type(name) ~= "string" then
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2) error(("Usage: AceDBObject:SetProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
end end
-- changing to the same profile, dont do anything -- changing to the same profile, dont do anything
@@ -471,7 +471,7 @@ end
-- @param tbl A table to store the profile names in (optional) -- @param tbl A table to store the profile names in (optional)
function DBObjectLib:GetProfiles(tbl) function DBObjectLib:GetProfiles(tbl)
if tbl and type(tbl) ~= "table" then if tbl and type(tbl) ~= "table" then
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2) error(("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected, got %q."):format(type(tbl)), 2)
end end
-- Clear the container table -- Clear the container table
@@ -509,15 +509,15 @@ end
-- @param silent If true, do not raise an error when the profile does not exist -- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:DeleteProfile(name, silent) function DBObjectLib:DeleteProfile(name, silent)
if type(name) ~= "string" then if type(name) ~= "string" then
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2) error(("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
end end
if self.keys.profile == name then if self.keys.profile == name then
error("Cannot delete the active profile in an AceDBObject.", 2) error(("Cannot delete the active profile (%q) in an AceDBObject."):format(name), 2)
end end
if not rawget(self.profiles, name) and not silent then if not rawget(self.profiles, name) and not silent then
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2) error(("Cannot delete profile %q as it does not exist."):format(name), 2)
end end
self.profiles[name] = nil self.profiles[name] = nil
@@ -548,15 +548,15 @@ end
-- @param silent If true, do not raise an error when the profile does not exist -- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:CopyProfile(name, silent) function DBObjectLib:CopyProfile(name, silent)
if type(name) ~= "string" then if type(name) ~= "string" then
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2) error(("Usage: AceDBObject:CopyProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
end end
if name == self.keys.profile then if name == self.keys.profile then
error("Cannot have the same source and destination profiles.", 2) error(("Cannot have the same source and destination profiles (%q)."):format(name), 2)
end end
if not rawget(self.profiles, name) and not silent then if not rawget(self.profiles, name) and not silent then
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2) error(("Cannot copy profile %q as it does not exist."):format(name), 2)
end end
-- Reset the profile before copying -- Reset the profile before copying
@@ -611,7 +611,7 @@ end
-- @param defaultProfile The profile name to use as the default -- @param defaultProfile The profile name to use as the default
function DBObjectLib:ResetDB(defaultProfile) function DBObjectLib:ResetDB(defaultProfile)
if defaultProfile and type(defaultProfile) ~= "string" then if defaultProfile and type(defaultProfile) ~= "string" then
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2) error(("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected, got %q."):format(type(defaultProfile)), 2)
end end
local sv = self.sv local sv = self.sv
@@ -619,8 +619,6 @@ function DBObjectLib:ResetDB(defaultProfile)
sv[k] = nil sv[k] = nil
end end
local parent = self.parent
initdb(sv, self.defaults, defaultProfile, self) initdb(sv, self.defaults, defaultProfile, self)
-- fix the child namespaces -- fix the child namespaces
@@ -647,13 +645,13 @@ end
-- @param defaults A table of values to use as defaults -- @param defaults A table of values to use as defaults
function DBObjectLib:RegisterNamespace(name, defaults) function DBObjectLib:RegisterNamespace(name, defaults)
if type(name) ~= "string" then if type(name) ~= "string" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2) error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected, got %q."):format(type(name)), 2)
end end
if defaults and type(defaults) ~= "table" then if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2) error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
end end
if self.children and self.children[name] then if self.children and self.children[name] then
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2) error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace called %q already exists."):format(name), 2)
end end
local sv = self.sv local sv = self.sv
@@ -677,10 +675,10 @@ end
-- @return the namespace object if found -- @return the namespace object if found
function DBObjectLib:GetNamespace(name, silent) function DBObjectLib:GetNamespace(name, silent)
if type(name) ~= "string" then if type(name) ~= "string" then
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2) error(("Usage: AceDBObject:GetNamespace(name): 'name' - string expected, got %q."):format(type(name)), 2)
end end
if not silent and not (self.children and self.children[name]) then if not silent and not (self.children and self.children[name]) then
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2) error(("Usage: AceDBObject:GetNamespace(name): 'name' - namespace %q does not exist."):format(name), 2)
end end
if not self.children then self.children = {} end if not self.children then self.children = {} end
return self.children[name] return self.children[name]
@@ -719,15 +717,15 @@ function AceDB:New(tbl, defaults, defaultProfile)
end end
if type(tbl) ~= "table" then if type(tbl) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2) error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected, got %q."):format(type(tbl)), 2)
end end
if defaults and type(defaults) ~= "table" then if defaults and type(defaults) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2) error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected, got %q."):format(type(defaults)), 2)
end end
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2) error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected, got %q."):format(type(defaultProfile)), 2)
end end
return initdb(tbl, defaults, defaultProfile) return initdb(tbl, defaults, defaultProfile)

View File

@@ -1,9 +1,9 @@
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles. --- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file -- @class file
-- @name AceDBOptions-3.0 -- @name AceDBOptions-3.0
-- @release $Id: AceDBOptions-3.0.lua 1140 2016-07-03 07:53:29Z nevcairiel $ -- @release $Id: AceDBOptions-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15 local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR) local AceDBOptions = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
if not AceDBOptions then return end -- No upgrade needed if not AceDBOptions then return end -- No upgrade needed

View File

@@ -24,14 +24,14 @@
-- f:AddChild(btn) -- f:AddChild(btn)
-- @class file -- @class file
-- @name AceGUI-3.0 -- @name AceGUI-3.0
-- @release $Id: AceGUI-3.0.lua 1228 2019-09-06 08:51:17Z nevcairiel $ -- @release $Id: AceGUI-3.0.lua 1247 2021-01-23 23:16:39Z funkehdude $
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 40 local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 41
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR) local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
if not AceGUI then return end -- No upgrade needed if not AceGUI then return end -- No upgrade needed
-- Lua APIs -- Lua APIs
local tinsert = table.insert local tinsert, wipe = table.insert, table.wipe
local select, pairs, next, type = select, pairs, next, type local select, pairs, next, type = select, pairs, next, type
local error, assert = error, assert local error, assert = error, assert
local setmetatable, rawget = setmetatable, rawget local setmetatable, rawget = setmetatable, rawget
@@ -212,6 +212,22 @@ function AceGUI:Release(widget)
delWidget(widget, widget.type) delWidget(widget, widget.type)
end end
--- Check if a widget is currently in the process of being released
-- This function check if this widget, or any of its parents (in which case it'll be released shortly as well)
-- are currently being released. This allows addon to handle any callbacks accordingly.
-- @param widget The widget to check
function AceGUI:IsReleasing(widget)
if widget.isQueuedForRelease then
return true
end
if widget.parent and widget.parent.AceGUIWidgetVersion then
return AceGUI:IsReleasing(widget.parent)
end
return false
end
----------- -----------
-- Focus -- -- Focus --
----------- -----------
@@ -338,6 +354,10 @@ do
AceGUI:Release(self) AceGUI:Release(self)
end end
WidgetBase.IsReleasing = function(self)
return AceGUI:IsReleasing(self)
end
WidgetBase.SetPoint = function(self, ...) WidgetBase.SetPoint = function(self, ...)
return self.frame:SetPoint(...) return self.frame:SetPoint(...)
end end

View File

@@ -2,7 +2,7 @@
BlizOptionsGroup Container BlizOptionsGroup Container
Simple container widget for the integration of AceGUI into the Blizzard Interface Options Simple container widget for the integration of AceGUI into the Blizzard Interface Options
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "BlizOptionsGroup", 21 local Type, Version = "BlizOptionsGroup", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -99,7 +99,7 @@ local methods = {
Constructor Constructor
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local function Constructor() local function Constructor()
local frame = CreateFrame("Frame") local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
frame:Hide() frame:Hide()
-- support functions for the Blizzard Interface Options -- support functions for the Blizzard Interface Options

View File

@@ -2,7 +2,7 @@
DropdownGroup Container DropdownGroup Container
Container controlled by a dropdown on the top. Container controlled by a dropdown on the top.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "DropdownGroup", 21 local Type, Version = "DropdownGroup", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -125,7 +125,7 @@ local function Constructor()
dropdown.frame:Show() dropdown.frame:Show()
dropdown:SetLabel("") dropdown:SetLabel("")
local border = CreateFrame("Frame", nil, frame) local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
border:SetPoint("TOPLEFT", 0, -26) border:SetPoint("TOPLEFT", 0, -26)
border:SetPoint("BOTTOMRIGHT", 0, 3) border:SetPoint("BOTTOMRIGHT", 0, 3)
border:SetBackdrop(PaneBackdrop) border:SetBackdrop(PaneBackdrop)

View File

@@ -1,7 +1,7 @@
--[[----------------------------------------------------------------------------- --[[-----------------------------------------------------------------------------
Frame Container Frame Container
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "Frame", 26 local Type, Version = "Frame", 28
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -83,6 +83,7 @@ local methods = {
["OnAcquire"] = function(self) ["OnAcquire"] = function(self)
self.frame:SetParent(UIParent) self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG") self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self.frame:SetFrameLevel(100) -- Lots of room to draw under it
self:SetTitle() self:SetTitle()
self:SetStatusText() self:SetStatusText()
self:ApplyStatus() self:ApplyStatus()
@@ -179,13 +180,14 @@ local PaneBackdrop = {
} }
local function Constructor() local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent) local frame = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
frame:Hide() frame:Hide()
frame:EnableMouse(true) frame:EnableMouse(true)
frame:SetMovable(true) frame:SetMovable(true)
frame:SetResizable(true) frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG") frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetFrameLevel(100) -- Lots of room to draw under it
frame:SetBackdrop(FrameBackdrop) frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0, 0, 0, 1) frame:SetBackdropColor(0, 0, 0, 1)
frame:SetMinResize(400, 200) frame:SetMinResize(400, 200)
@@ -201,7 +203,7 @@ local function Constructor()
closebutton:SetWidth(100) closebutton:SetWidth(100)
closebutton:SetText(CLOSE) closebutton:SetText(CLOSE)
local statusbg = CreateFrame("Button", nil, frame) local statusbg = CreateFrame("Button", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
statusbg:SetPoint("BOTTOMLEFT", 15, 15) statusbg:SetPoint("BOTTOMLEFT", 15, 15)
statusbg:SetPoint("BOTTOMRIGHT", -132, 15) statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
statusbg:SetHeight(24) statusbg:SetHeight(24)

View File

@@ -2,7 +2,7 @@
InlineGroup Container InlineGroup Container
Simple container widget that creates a visible "box" with an optional title. Simple container widget that creates a visible "box" with an optional title.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "InlineGroup", 21 local Type, Version = "InlineGroup", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -75,7 +75,7 @@ local function Constructor()
titletext:SetJustifyH("LEFT") titletext:SetJustifyH("LEFT")
titletext:SetHeight(18) titletext:SetHeight(18)
local border = CreateFrame("Frame", nil, frame) local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
border:SetPoint("TOPLEFT", 0, -17) border:SetPoint("TOPLEFT", 0, -17)
border:SetPoint("BOTTOMRIGHT", -1, 3) border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop) border:SetBackdrop(PaneBackdrop)

View File

@@ -2,12 +2,12 @@
TabGroup Container TabGroup Container
Container that uses tabs on top to switch between groups. Container that uses tabs on top to switch between groups.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "TabGroup", 36 local Type, Version = "TabGroup", 37
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs -- Lua APIs
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, table.wipe
-- WoW APIs -- WoW APIs
local PlaySound = PlaySound local PlaySound = PlaySound
@@ -316,7 +316,7 @@ local function Constructor()
titletext:SetHeight(18) titletext:SetHeight(18)
titletext:SetText("") titletext:SetText("")
local border = CreateFrame("Frame", nil, frame) local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
border:SetPoint("TOPLEFT", 1, -27) border:SetPoint("TOPLEFT", 1, -27)
border:SetPoint("BOTTOMRIGHT", -1, 3) border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop) border:SetBackdrop(PaneBackdrop)

View File

@@ -2,12 +2,10 @@
TreeGroup Container TreeGroup Container
Container that uses a tree control to switch between groups. Container that uses a tree control to switch between groups.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "TreeGroup", 44 local Type, Version = "TreeGroup", 45
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local WoW80 = select(4, GetBuildInfo()) >= 80000
-- Lua APIs -- Lua APIs
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
local math_min, math_max, floor = math.min, math.max, floor local math_min, math_max, floor = math.min, math.max, floor
@@ -422,8 +420,7 @@ local methods = {
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18)) local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
if maxlines <= 0 then return end if maxlines <= 0 then return end
-- workaround for lag spikes on WoW 8.0 if self.frame:GetParent() == UIParent and not fromOnUpdate then
if WoW80 and self.frame:GetParent() == UIParent and not fromOnUpdate then
self.frame:SetScript("OnUpdate", FirstFrameUpdate) self.frame:SetScript("OnUpdate", FirstFrameUpdate)
return return
end end
@@ -632,7 +629,7 @@ local PaneBackdrop = {
local DraggerBackdrop = { local DraggerBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = nil, edgeFile = nil,
tile = true, tileSize = 16, edgeSize = 0, tile = true, tileSize = 16, edgeSize = 1,
insets = { left = 3, right = 3, top = 7, bottom = 7 } insets = { left = 3, right = 3, top = 7, bottom = 7 }
} }
@@ -640,7 +637,7 @@ local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type) local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent) local frame = CreateFrame("Frame", nil, UIParent)
local treeframe = CreateFrame("Frame", nil, frame) local treeframe = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
treeframe:SetPoint("TOPLEFT") treeframe:SetPoint("TOPLEFT")
treeframe:SetPoint("BOTTOMLEFT") treeframe:SetPoint("BOTTOMLEFT")
treeframe:SetWidth(DEFAULT_TREE_WIDTH) treeframe:SetWidth(DEFAULT_TREE_WIDTH)
@@ -655,7 +652,7 @@ local function Constructor()
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged) treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel) treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
local dragger = CreateFrame("Frame", nil, treeframe) local dragger = CreateFrame("Frame", nil, treeframe, BackdropTemplateMixin and "BackdropTemplate" or nil)
dragger:SetWidth(8) dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT") dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT") dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
@@ -680,7 +677,7 @@ local function Constructor()
scrollbg:SetAllPoints(scrollbar) scrollbg:SetAllPoints(scrollbar)
scrollbg:SetColorTexture(0,0,0,0.4) scrollbg:SetColorTexture(0,0,0,0.4)
local border = CreateFrame("Frame",nil,frame) local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT") border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
border:SetPoint("BOTTOMRIGHT") border:SetPoint("BOTTOMRIGHT")
border:SetBackdrop(PaneBackdrop) border:SetBackdrop(PaneBackdrop)

View File

@@ -1,4 +1,4 @@
--[[ $Id: AceGUIWidget-DropDown.lua 1209 2019-06-24 21:01:01Z nevcairiel $ ]]-- --[[ $Id: AceGUIWidget-DropDown.lua 1239 2020-09-20 10:22:02Z nevcairiel $ ]]--
local AceGUI = LibStub("AceGUI-3.0") local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs -- Lua APIs
@@ -39,7 +39,7 @@ end
do do
local widgetType = "Dropdown-Pullout" local widgetType = "Dropdown-Pullout"
local widgetVersion = 3 local widgetVersion = 5
--[[ Static data ]]-- --[[ Static data ]]--
@@ -193,12 +193,7 @@ do
local height = 8 local height = 8
for i, item in pairs(items) do for i, item in pairs(items) do
if i == 1 then item:SetPoint("TOP", itemFrame, "TOP", 0, -2 + (i - 1) * -16)
item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
else
item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
end
item:Show() item:Show()
height = height + 16 height = height + 16
@@ -258,7 +253,7 @@ do
local function Constructor() local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType) local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent) local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
local self = {} local self = {}
self.count = count self.count = count
self.type = widgetType self.type = widgetType
@@ -309,7 +304,7 @@ do
scrollFrame.obj = self scrollFrame.obj = self
itemFrame.obj = self itemFrame.obj = self
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame) local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame, BackdropTemplateMixin and "BackdropTemplate" or nil)
slider:SetOrientation("VERTICAL") slider:SetOrientation("VERTICAL")
slider:SetHitRectInsets(0, 0, -10, 0) slider:SetHitRectInsets(0, 0, -10, 0)
slider:SetBackdrop(sliderBackdrop) slider:SetBackdrop(sliderBackdrop)
@@ -356,7 +351,7 @@ end
do do
local widgetType = "Dropdown" local widgetType = "Dropdown"
local widgetVersion = 34 local widgetVersion = 35
--[[ Static data ]]-- --[[ Static data ]]--
@@ -465,6 +460,7 @@ do
self:SetWidth(200) self:SetWidth(200)
self:SetLabel() self:SetLabel()
self:SetPulloutWidth(nil) self:SetPulloutWidth(nil)
self.list = {}
end end
-- exported, AceGUI callback -- exported, AceGUI callback
@@ -535,9 +531,7 @@ do
-- exported -- exported
local function SetValue(self, value) local function SetValue(self, value)
if self.list then
self:SetText(self.list[value] or "") self:SetText(self.list[value] or "")
end
self.value = value self.value = value
end end
@@ -601,7 +595,7 @@ do
end end
end end
local function SetList(self, list, order, itemType) local function SetList(self, list, order, itemType)
self.list = list self.list = list or {}
self.pullout:Clear() self.pullout:Clear()
self.hasClose = nil self.hasClose = nil
if not list then return end if not list then return end
@@ -629,11 +623,9 @@ do
-- exported -- exported
local function AddItem(self, value, text, itemType) local function AddItem(self, value, text, itemType)
if self.list then
self.list[value] = text self.list[value] = text
AddListItem(self, value, text, itemType) AddListItem(self, value, text, itemType)
end end
end
-- exported -- exported
local function SetMultiselect(self, multi) local function SetMultiselect(self, multi)

View File

@@ -2,7 +2,7 @@
Keybinding Widget Keybinding Widget
Set Keybindings in the Config UI. Set Keybindings in the Config UI.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "Keybinding", 25 local Type, Version = "Keybinding", 26
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -214,7 +214,7 @@ local function Constructor()
label:SetJustifyH("CENTER") label:SetJustifyH("CENTER")
label:SetHeight(18) label:SetHeight(18)
local msgframe = CreateFrame("Frame", nil, UIParent) local msgframe = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
msgframe:SetHeight(30) msgframe:SetHeight(30)
msgframe:SetBackdrop(ControlBackdrop) msgframe:SetBackdrop(ControlBackdrop)
msgframe:SetBackdropColor(0,0,0) msgframe:SetBackdropColor(0,0,0)

View File

@@ -2,7 +2,7 @@
Label Widget Label Widget
Displays text and optionally an icon. Displays text and optionally an icon.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "Label", 26 local Type, Version = "Label", 27
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -130,6 +130,7 @@ local methods = {
["SetFont"] = function(self, font, height, flags) ["SetFont"] = function(self, font, height, flags)
self.label:SetFont(font, height, flags) self.label:SetFont(font, height, flags)
UpdateImageAnchor(self)
end, end,
["SetFontObject"] = function(self, font) ["SetFontObject"] = function(self, font)

View File

@@ -1,4 +1,4 @@
local Type, Version = "MultiLineEditBox", 28 local Type, Version = "MultiLineEditBox", 29
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -297,7 +297,7 @@ local function Constructor()
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1) text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
text:SetJustifyV("MIDDLE") text:SetJustifyV("MIDDLE")
local scrollBG = CreateFrame("Frame", nil, frame) local scrollBG = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
scrollBG:SetBackdrop(backdrop) scrollBG:SetBackdrop(backdrop)
scrollBG:SetBackdropColor(0, 0, 0) scrollBG:SetBackdropColor(0, 0, 0)
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4) scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)

View File

@@ -2,7 +2,7 @@
Slider Widget Slider Widget
Graphical Slider, like, for Range values. Graphical Slider, like, for Range values.
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local Type, Version = "Slider", 22 local Type, Version = "Slider", 23
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -225,7 +225,7 @@ local function Constructor()
label:SetJustifyH("CENTER") label:SetJustifyH("CENTER")
label:SetHeight(15) label:SetHeight(15)
local slider = CreateFrame("Slider", nil, frame) local slider = CreateFrame("Slider", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
slider:SetOrientation("HORIZONTAL") slider:SetOrientation("HORIZONTAL")
slider:SetHeight(15) slider:SetHeight(15)
slider:SetHitRectInsets(0, 0, -10, 0) slider:SetHitRectInsets(0, 0, -10, 0)
@@ -247,7 +247,7 @@ local function Constructor()
local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3) hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
local editbox = CreateFrame("EditBox", nil, frame) local editbox = CreateFrame("EditBox", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
editbox:SetAutoFocus(false) editbox:SetAutoFocus(false)
editbox:SetFontObject(GameFontHighlightSmall) editbox:SetFontObject(GameFontHighlightSmall)
editbox:SetPoint("TOP", slider, "BOTTOM") editbox:SetPoint("TOP", slider, "BOTTOM")

View File

@@ -9,8 +9,8 @@
-- make into AceHook. -- make into AceHook.
-- @class file -- @class file
-- @name AceHook-3.0 -- @name AceHook-3.0
-- @release $Id: AceHook-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $ -- @release $Id: AceHook-3.0.lua 1243 2020-10-18 00:00:19Z nevcairiel $
local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 8 local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 9
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR) local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
if not AceHook then return end -- No upgrade needed if not AceHook then return end -- No upgrade needed
@@ -478,10 +478,10 @@ function AceHook:UnhookAll()
for key, value in pairs(registry[self]) do for key, value in pairs(registry[self]) do
if type(key) == "table" then if type(key) == "table" then
for method in pairs(value) do for method in pairs(value) do
self:Unhook(key, method) AceHook.Unhook(self, key, method)
end end
else else
self:Unhook(key) AceHook.Unhook(self, key)
end end
end end
end end

View File

@@ -1,4 +1,4 @@
--[[ $Id: CallbackHandler-1.0.lua 22 2018-07-21 14:17:22Z nevcairiel $ ]] --[[ $Id: CallbackHandler-1.0.lua 1186 2018-07-21 14:19:18Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 7 local MAJOR, MINOR = "CallbackHandler-1.0", 7
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR) local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)

View File

@@ -6,7 +6,7 @@
-- --
local DBICON10 = "LibDBIcon-1.0" local DBICON10 = "LibDBIcon-1.0"
local DBICON10_MINOR = 43 -- Bump on changes local DBICON10_MINOR = 44 -- Bump on changes
if not LibStub then error(DBICON10 .. " requires LibStub.") end if not LibStub then error(DBICON10 .. " requires LibStub.") end
local ldb = LibStub("LibDataBroker-1.1", true) local ldb = LibStub("LibDataBroker-1.1", true)
if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
@@ -18,8 +18,8 @@ lib.callbackRegistered = lib.callbackRegistered or nil
lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
lib.notCreated = lib.notCreated or {} lib.notCreated = lib.notCreated or {}
lib.radius = lib.radius or 5 lib.radius = lib.radius or 5
local next, Minimap, CreateFrame = next, Minimap, CreateFrame
lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate") lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate")
local next, Minimap = next, Minimap
local isDraggingButton = false local isDraggingButton = false
function lib:IconCallback(event, name, key, value) function lib:IconCallback(event, name, key, value)
@@ -218,8 +218,14 @@ local function createButton(name, object, db)
button.dataObject = object button.dataObject = object
button.db = db button.db = db
button:SetFrameStrata("MEDIUM") button:SetFrameStrata("MEDIUM")
button:SetSize(31, 31) if button.SetFixedFrameStrata then -- Classic support
button:SetFixedFrameStrata(true)
end
button:SetFrameLevel(8) button:SetFrameLevel(8)
if button.SetFixedFrameLevel then -- Classic support
button:SetFixedFrameLevel(true)
end
button:SetSize(31, 31)
button:RegisterForClicks("anyUp") button:RegisterForClicks("anyUp")
button:RegisterForDrag("LeftButton") button:RegisterForDrag("LeftButton")
button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight" button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight"

View File

@@ -1,13 +1,22 @@
-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info -- 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 is hereby placed in the Public Domain
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR] local LibStub = _G[LIBSTUB_MAJOR]
-- Check to see is this version of the stub is obsolete
if not LibStub or LibStub.minor < LIBSTUB_MINOR then if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} } LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub _G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR LibStub.minor = LIBSTUB_MINOR
-- LibStub:NewLibrary(major, minor)
-- major (string) - the major version of the library
-- minor (string or number ) - the minor version of the library
--
-- returns nil if a newer or same version of the lib is already present
-- returns empty library object or old library object if upgrade is needed
function LibStub:NewLibrary(major, minor) function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
@@ -18,6 +27,12 @@ if not LibStub or LibStub.minor < LIBSTUB_MINOR then
return self.libs[major], oldminor return self.libs[major], oldminor
end end
-- LibStub:GetLibrary(major, [silent])
-- major (string) - the major version of the library
-- silent (boolean) - if true, library is optional, silently return nil if its not found
--
-- throws an error if the library can not be found (except silent is set)
-- returns the library object if found
function LibStub:GetLibrary(major, silent) function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
@@ -25,6 +40,12 @@ if not LibStub or LibStub.minor < LIBSTUB_MINOR then
return self.libs[major], self.minors[major] return self.libs[major], self.minors[major]
end end
function LibStub:IterateLibraries() return pairs(self.libs) end -- LibStub:IterateLibraries()
--
-- Returns an iterator for the currently registered libraries
function LibStub:IterateLibraries()
return pairs(self.libs)
end
setmetatable(LibStub, { __call = LibStub.GetLibrary }) setmetatable(LibStub, { __call = LibStub.GetLibrary })
end end

View File

@@ -1,9 +0,0 @@
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
LibStub.lua

View File

@@ -1,17 +0,0 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="Libs\LibStub\LibStub.lua"/>
<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
<Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/>
<Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" />
<Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml" />
<Include file="Libs\AceHook-3.0\AceHook-3.0.xml"/>
<Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/>
<Include file="Libs\AceDB-3.0\AceDB-3.0.xml"/>
<Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
<Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/>
<Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/>
<Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua" />
<Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua" />
</Ui>

View File

@@ -15,7 +15,7 @@ local cPrefix = Grichelde.F.cPrefix
L.AddonName = "Grichelde" L.AddonName = "Grichelde"
L.AddonNamePlusVersion = "%s v%s" L.AddonNamePlusVersion = "%s v%s"
L.AddonLoaded = "%s unterst\195\188tzt Euch jetzt bei euren Sprachschwierigkeiten." L.AddonLoaded = "%s unterst\195\188tzt Euch jetzt bei euren Sprachschwierigkeiten."
L.AddonUnloaded = "%s wartet geduldig Euch weiter unterst\195\188tzen zu d\195\188rfen." L.AddonUnloaded = "%s erwartet geduldig Euch weiter unterst\195\188tzen zu d\195\188rfen."
L.Upgrade_ToVersion = "Hebe Databank auf Version %s an." L.Upgrade_ToVersion = "Hebe Databank auf Version %s an."
L.Upgrade_Successful = "Upgrade erfolgreich." L.Upgrade_Successful = "Upgrade erfolgreich."
L.Upgrade_Error = "Upgrade fehlgeschlagen!" L.Upgrade_Error = "Upgrade fehlgeschlagen!"

View File

@@ -15,7 +15,7 @@ local cPrefix = Grichelde.F.cPrefix
L.AddonName = "Grichelde" L.AddonName = "Grichelde"
L.AddonNamePlusVersion = "%s v%s" L.AddonNamePlusVersion = "%s v%s"
L.AddonLoaded = "%s happily assists you with your spelling disabilities now." L.AddonLoaded = "%s happily assists you with your spelling disabilities now."
L.AddonUnloaded = "%s patiently waits to support you again when needed." L.AddonUnloaded = "%s patiently awaits to support you again."
L.Upgrade_ToVersion = "Upgrade database to version %s." L.Upgrade_ToVersion = "Upgrade database to version %s."
L.Upgrade_Successful = "Upgrade successful." L.Upgrade_Successful = "Upgrade successful."
L.Upgrade_Error = "Upgrade failed!" L.Upgrade_Error = "Upgrade failed!"