├── .pkgmeta
├── tests
├── AceSerializer-3.0.lua
├── AceGUITest
│ └── AceGUITest.toc
├── runall.sh
├── runall.bat
├── check_globals.sh
├── AceGUI-3.0-recycle.lua
├── serialize.lua
├── AceDB-3.0-namespaces.lua
├── AceDB-3.0-callbacks.lua
├── AceTimer-3.0-test3.lua
├── LibStub.lua
├── AceComm-3.0-callbacks.lua
├── AceAddon-3.0.lua
├── AceLocale-3.0.lua
├── AceConfigCmd-3.0-ordering.lua
├── ChatThrottleLib-callbackerrors.lua
├── AceConfigRegisty-3.0-errors.lua
├── ChatThrottleLib-upgrade-20-current.lua
├── AceLocale-3.0-test2.lua
├── AceConsole-3.0-GetArgs.lua
├── AceTimer-3.0-test2.lua
├── ChatThrottleLib-upgrade-14-20-current.lua
├── AceComm-3.0-pre-4.1.lua
├── AceTimer-3.0-test1.lua
├── AceConfigCmd-3.0.lua
├── AceTimer-3.0-ACE94.lua
├── AceDB-3.0-defaults.lua
├── AceDB-3.0.lua
├── AceComm-3.0.lua
├── wow_api.lua
└── AceEvent-3.0.lua
├── Bindings.xml
├── AceDB-3.0
└── AceDB-3.0.xml
├── .editorconfig
├── AceAddon-3.0
└── AceAddon-3.0.xml
├── AceEvent-3.0
├── AceEvent-3.0.xml
└── AceEvent-3.0.lua
├── AceHook-3.0
└── AceHook-3.0.xml
├── AceTab-3.0
└── AceTab-3.0.xml
├── AceTimer-3.0
└── AceTimer-3.0.xml
├── AceBucket-3.0
└── AceBucket-3.0.xml
├── AceConsole-3.0
└── AceConsole-3.0.xml
├── AceLocale-3.0
├── AceLocale-3.0.xml
└── AceLocale-3.0.lua
├── AceDBOptions-3.0
└── AceDBOptions-3.0.xml
├── AceSerializer-3.0
└── AceSerializer-3.0.xml
├── CallbackHandler-1.0
└── CallbackHandler-1.0.xml
├── AceConfig-3.0
├── AceConfigCmd-3.0
│ └── AceConfigCmd-3.0.xml
├── AceConfigDialog-3.0
│ └── AceConfigDialog-3.0.xml
├── AceConfigRegistry-3.0
│ └── AceConfigRegistry-3.0.xml
├── AceConfig-3.0.xml
└── AceConfig-3.0.lua
├── AceComm-3.0
└── AceComm-3.0.xml
├── .gitattributes
├── .gitignore
├── .github
└── workflows
│ ├── pull_request.yml
│ └── ci.yml
├── Ace3.toc
├── README.md
├── LibStub
└── LibStub.lua
├── AceGUI-3.0
├── AceGUI-3.0.xml
└── widgets
│ ├── AceGUIContainer-SimpleGroup.lua
│ ├── AceGUIWidget-Heading.lua
│ ├── AceGUIWidget-InteractiveLabel.lua
│ ├── AceGUIWidget-Button.lua
│ ├── AceGUIContainer-InlineGroup.lua
│ ├── AceGUIContainer-BlizOptionsGroup.lua
│ ├── AceGUIWidget-Icon.lua
│ ├── AceGUIContainer-DropDownGroup.lua
│ ├── AceGUIWidget-Label.lua
│ ├── AceGUIWidget-ColorPicker.lua
│ ├── AceGUIContainer-ScrollFrame.lua
│ ├── AceGUIWidget-Keybinding.lua
│ └── AceGUIWidget-EditBox.lua
├── LICENSE.txt
├── .luacheckrc
└── Ace3.lua
/.pkgmeta:
--------------------------------------------------------------------------------
1 | package-as: Ace3
2 |
3 | ignore:
4 | - tests
--------------------------------------------------------------------------------
/tests/AceSerializer-3.0.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WoWUIDev/Ace3/HEAD/tests/AceSerializer-3.0.lua
--------------------------------------------------------------------------------
/Bindings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ReloadUI()
4 |
5 |
6 |
--------------------------------------------------------------------------------
/tests/AceGUITest/AceGUITest.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 20200
2 |
3 | ## Title: AceGUITest
4 |
5 | ## Author: Nargiddley
6 | ## Version: Alpha
7 | ## OptionalDeps: LibStub, Ace3
8 |
9 | LibStub.lua
10 | test.lua
--------------------------------------------------------------------------------
/AceDB-3.0/AceDB-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = tab
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
--------------------------------------------------------------------------------
/AceAddon-3.0/AceAddon-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceEvent-3.0/AceEvent-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceHook-3.0/AceHook-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceTab-3.0/AceTab-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/AceTimer-3.0/AceTimer-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceBucket-3.0/AceBucket-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceConsole-3.0/AceConsole-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceLocale-3.0/AceLocale-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceDBOptions-3.0/AceDBOptions-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceSerializer-3.0/AceSerializer-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/CallbackHandler-1.0/CallbackHandler-1.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/AceComm-3.0/AceComm-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto !eol
2 | /.editorconfig -text
3 | /.pkgmeta -text
4 | /LICENSE.txt svneol=native#text/plain
5 | tests/AceAddon-3.0.lua svneol=native#text/plain
6 | tests/AceComm-3.0-pre-4.1.lua -text
7 | tests/AceDB-3.0.lua svneol=native#text/plain
8 | tests/AceEvent-3.0.lua svneol=native#text/plain
9 | tests/LibStub.lua svneol=native#text/plain
10 | tests/wow_api.lua svneol=native#text/plain
11 |
--------------------------------------------------------------------------------
/tests/runall.sh:
--------------------------------------------------------------------------------
1 | echo
2 | echo Running all -?.x test cases:
3 | echo
4 |
5 | if [ -z $lua ]; then
6 | lua=lua
7 | fi
8 |
9 | for i in *-?.*.lua ChatThrottleLib*.lua; do
10 | echo ----- Running $i:
11 | $lua $i
12 | done
13 |
14 |
15 | echo
16 | echo -----------------------
17 | echo DONE!
18 | echo
19 | echo '(To point at a specific lua.exe, use "export lua=/path/to/lua" prior to executing runall.sh)'
20 | echo
21 |
--------------------------------------------------------------------------------
/tests/runall.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo.
3 | echo Running all -?.x test cases:
4 | echo.
5 |
6 | setlocal
7 | if _%lua%_==__ set lua=lua
8 |
9 | for %%i in (*-?.*.lua) do call :runtest %%i
10 |
11 |
12 | echo.
13 | echo -----------------------
14 | echo DONE!
15 | echo.
16 | echo (To point at a specific lua.exe, use "set lua=c:\path\to\lua.exe" prior to executing %0)
17 | echo.
18 | pause
19 | goto :eof
20 |
21 |
22 | :runtest
23 | echo ----- Running %1:
24 | %lua% %1
25 | goto :eof
26 |
--------------------------------------------------------------------------------
/AceConfig-3.0/AceConfig-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.iml
2 | /.idea
3 | AceAddon-3.0/*.toc
4 | AceBucket-3.0/*.toc
5 | AceComm-3.0/*.toc
6 | AceConfig-3.0/*.toc
7 | AceConfig-3.0/AceConfigCmd-3.0/*.toc
8 | AceConfig-3.0/AceConfigDialog-3.0/*.toc
9 | AceConfig-3.0/AceConfigDropdown-3.0/*.toc
10 | AceConfig-3.0/AceConfigRegistry-3.0/*.toc
11 | AceConsole-3.0/*.toc
12 | AceDB-3.0/*.toc
13 | AceEvent-3.0/*.toc
14 | AceGUI-3.0/*.toc
15 | AceGUI-3.0/widgets/*.toc
16 | AceHook-3.0/*.toc
17 | AceLocale-3.0/*.toc
18 | AceLocale-3.0/luac.out
19 | AceSerializer-3.0/*.toc
20 | AceTimer-3.0/*.toc
21 | CallbackHandler-1.0/*.toc
22 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: CI-PR
4 |
5 | on: [pull_request]
6 |
7 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
8 | jobs:
9 | # This workflow contains a single job called "build"
10 | build:
11 | # The type of runner that the job will run on
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: Install and run Luacheck
17 | run: |
18 | sudo apt-get install luarocks
19 | luarocks install --local luacheck
20 | /home/runner/.luarocks/bin/luacheck . --no-color -q
21 |
--------------------------------------------------------------------------------
/tests/check_globals.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Checking all Ace3 files"
4 |
5 | foundGlobals=0
6 | for listing in `find .. -name "*.lua" -print`; do
7 | dir=`echo $listing | awk -F '/' '{print $2}'`
8 | file=`echo $listing | sed 's/^[^/]*\/[^/]*\/\(.*\)$/\1/'`
9 | if [[ $dir != "tests" && $dir != "benchs" ]]; then
10 | res=`luac -p -l "$listing" | grep SETGLOBAL`
11 | if [[ $? == 0 ]]; then
12 | if [[ $foundGlobals == 0 ]]; then
13 | tput bold
14 | echo "Globals found:"
15 | tput sgr0
16 | fi
17 | foundGlobals=1
18 | echo "$listing:"
19 | echo $res | awk 'BEGIN { format = "%--50s \033[32m%s\033[0m\n" } { printf format, $7, $2 }'
20 | fi;
21 | fi;
22 | done
23 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: CI
4 |
5 | # Controls when the action will run. Triggers the workflow on push or pull request
6 | # events but only for the master branch
7 | on:
8 | push:
9 | branches: [ master ]
10 | tags:
11 | - '**'
12 |
13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
14 | jobs:
15 | # This workflow contains a single job called "build"
16 | build:
17 | # The type of runner that the job will run on
18 | runs-on: ubuntu-latest
19 |
20 | steps:
21 | - uses: actions/checkout@v3
22 | - name: Install and run Luacheck
23 | run: |
24 | sudo apt-get install luarocks
25 | luarocks install --local luacheck
26 | /home/runner/.luarocks/bin/luacheck . --no-color -q
27 |
--------------------------------------------------------------------------------
/Ace3.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 11508, 11507, 20505, 30405, 38000, 40402, 50503, 50502, 110205, 110207, 120000
2 |
3 | ## Title: Lib: Ace3
4 | ## Notes: AddOn development framework
5 | ## Author: Ace3 Development Team
6 | ## X-Website: http://www.wowace.com
7 | ## X-Category: Library
8 | ## X-License: Limited BSD
9 | ## Version: @project-version@
10 |
11 | LibStub\LibStub.lua
12 | CallbackHandler-1.0\CallbackHandler-1.0.xml
13 | AceAddon-3.0\AceAddon-3.0.xml
14 | AceEvent-3.0\AceEvent-3.0.xml
15 | AceTimer-3.0\AceTimer-3.0.xml
16 | AceBucket-3.0\AceBucket-3.0.xml
17 | AceHook-3.0\AceHook-3.0.xml
18 | AceDB-3.0\AceDB-3.0.xml
19 | AceDBOptions-3.0\AceDBOptions-3.0.xml
20 | AceLocale-3.0\AceLocale-3.0.xml
21 | AceConsole-3.0\AceConsole-3.0.xml
22 | AceGUI-3.0\AceGUI-3.0.xml
23 | AceConfig-3.0\AceConfig-3.0.xml
24 | AceComm-3.0\AceComm-3.0.xml
25 | AceTab-3.0\AceTab-3.0.xml
26 | AceSerializer-3.0\AceSerializer-3.0.xml
27 |
28 | Ace3.lua
29 |
--------------------------------------------------------------------------------
/tests/AceGUI-3.0-recycle.lua:
--------------------------------------------------------------------------------
1 |
2 | dofile("wow_api.lua")
3 | dofile("LibStub.lua")
4 | dofile("../AceGUI-3.0/AceGUI-3.0.lua")
5 |
6 | local AceGUI = LibStub("AceGUI-3.0")
7 |
8 | -- create dummy widget
9 | do
10 | local Type = "Example"
11 |
12 | local function Acquire(self)
13 |
14 | end
15 |
16 | local function Release(self)
17 |
18 | end
19 |
20 |
21 | local function Constructor()
22 | local frame = CreateFrame("Frame",nil,UIParent)
23 | local self = {}
24 | self.type = Type
25 |
26 | self.Release = Release
27 | self.Acquire = Acquire
28 |
29 | self.frame = frame
30 | frame.obj = self
31 |
32 | AceGUI:RegisterAsWidget(self)
33 | return self
34 | end
35 |
36 | AceGUI:RegisterWidgetType(Type,Constructor, 1)
37 | end
38 |
39 | local widget1 = AceGUI:Create("Example")
40 | AceGUI:Release(widget1)
41 |
42 | LibStub.minors["AceGUI-3.0"] = 29
43 |
44 | dofile("../AceGUI-3.0/AceGUI-3.0.lua")
45 |
46 | local widget2 = AceGUI:Create("Example")
47 |
48 | assert(widget1 == widget2)
49 |
50 | print("OK")
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Ace3 - AddOn development framework
2 | ==================================
3 |
4 | Ace3 is a comprehensive framework for WoW AddOn development to streamline many of the common tasks in developing addons. This includes lifecycles, saved variables, configuration, event handling, network communications, and more.
5 |
6 | Documentation
7 | -------------
8 |
9 | A basic introduction to usage can be found here:
10 | https://www.wowace.com/projects/ace3/pages/getting-started
11 |
12 | Documentation can be found here:
13 | https://www.wowace.com/addons/ace3/pages/
14 |
15 | Resources
16 | ---------
17 | A development repository is available on GitHub:
18 | https://github.com/WoWUIDev/Ace3
19 |
20 | Please note that the CurseForge/WoWAce SVN repository remains the primary authority, and what should be used in .pkgmeta to reference Ace3.
21 |
22 | .pkgmeta reference:
23 | Base Path: https://repos.wowace.com/wow/ace3/trunk
24 | Example for AceAddon-3.0: https://repos.wowace.com/wow/ace3/trunk/AceAddon-3.0
25 |
26 | It is recommended to reference the specific Ace3 libraries you are using directly, instead of pulling in the entire package.
27 |
--------------------------------------------------------------------------------
/tests/serialize.lua:
--------------------------------------------------------------------------------
1 | local recurse = false
2 | function serialize(o, indent, file)
3 | if not file then file = io.stdout end
4 |
5 | if type(o) == "number" then
6 | file:write(o)
7 | elseif type(o) == "string" then
8 | file:write(string.format("%q", o))
9 | elseif type(o) == "boolean" then
10 | file:write(o and "true" or "false")
11 | elseif type(o) == "function" then
12 | file:write("nil --[["..tostring(o).."]]")
13 | elseif type(o) == "table" then
14 | if not indent then indent = " " else indent = indent .. " " end
15 | local old = recurse
16 | recurse = true
17 | file:write("{\n")
18 | -- Check to see if we have an integer section
19 | if #o > 0 then
20 | for k,v in ipairs(o) do
21 | file:write(indent)
22 | serialize(v, indent, file)
23 | file:write(",\n")
24 | end
25 | end
26 |
27 | for k,v in pairs(o) do
28 | local mask
29 | if type(k) == "number" and #o > 0 and k > 0 and k <= #o then
30 | mask = true
31 | end
32 |
33 | if not mask then
34 | file:write(indent .. "[")
35 | serialize(k, indent, file)
36 | file:write("] = ")
37 | serialize(v, indent, file)
38 | file:write(",\n")
39 | end
40 | end
41 | recurse = old
42 | file:write(string.sub(indent,1,-3) .. (recurse and "}" or "}\n"))
43 | else
44 | error("Cannot serialize a " .. type(o))
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/LibStub/LibStub.lua:
--------------------------------------------------------------------------------
1 | -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
2 | -- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
3 | local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
4 | local LibStub = _G[LIBSTUB_MAJOR]
5 |
6 | if not LibStub or LibStub.minor < LIBSTUB_MINOR then
7 | LibStub = LibStub or {libs = {}, minors = {} }
8 | _G[LIBSTUB_MAJOR] = LibStub
9 | LibStub.minor = LIBSTUB_MINOR
10 |
11 | function LibStub:NewLibrary(major, minor)
12 | assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
13 | minor = assert(tonumber(string.match(minor, "%d+")), "Minor version must either be a number or contain a number.")
14 |
15 | local oldminor = self.minors[major]
16 | if oldminor and oldminor >= minor then return nil end
17 | self.minors[major], self.libs[major] = minor, self.libs[major] or {}
18 | return self.libs[major], oldminor
19 | end
20 |
21 | function LibStub:GetLibrary(major, silent)
22 | if not self.libs[major] and not silent then
23 | error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
24 | end
25 | return self.libs[major], self.minors[major]
26 | end
27 |
28 | function LibStub:IterateLibraries() return pairs(self.libs) end
29 | setmetatable(LibStub, { __call = LibStub.GetLibrary })
30 | end
31 |
--------------------------------------------------------------------------------
/AceGUI-3.0/AceGUI-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2007, Ace3 Development Team
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | * Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 | * Redistribution of a stand alone version is strictly prohibited without
14 | prior written authorization from the Lead of the Ace3 Development Team.
15 | * Neither the name of the Ace3 Development Team nor the names of its contributors
16 | may be used to endorse or promote products derived from this software without
17 | specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/tests/AceDB-3.0-namespaces.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceDB-3.0/AceDB-3.0.lua")
5 | dofile("serialize.lua")
6 |
7 | do
8 | local defaults = { profile = { key3 = "stillfun" } }
9 | local db = LibStub("AceDB-3.0"):New({})
10 | local namespace = db:RegisterNamespace("test", defaults)
11 |
12 | namespace.profile.key1 = "fun"
13 | namespace.profile.key2 = "nofun"
14 |
15 | local oldprofile = db:GetCurrentProfile()
16 | db:SetProfile("newprofile")
17 | assert(namespace.profile.key1 == nil)
18 | assert(namespace.profile.key2 == nil)
19 | assert(namespace.profile.key3 == "stillfun")
20 | db:SetProfile(oldprofile)
21 | assert(namespace.profile.key1 == "fun")
22 | assert(namespace.profile.key2 == "nofun")
23 | assert(namespace.profile.key3 == "stillfun")
24 | db:SetProfile("newprofile2")
25 | db:CopyProfile(oldprofile)
26 | assert(namespace.profile.key1 == "fun")
27 | assert(namespace.profile.key2 == "nofun")
28 | assert(namespace.profile.key3 == "stillfun")
29 | db:ResetProfile()
30 | assert(namespace.profile.key1 == nil)
31 | assert(namespace.profile.key2 == nil)
32 | assert(namespace.profile.key3 == "stillfun")
33 | db:DeleteProfile(oldprofile)
34 | db:SetProfile(oldprofile)
35 | assert(namespace.profile.key1 == nil)
36 | assert(namespace.profile.key2 == nil)
37 | assert(namespace.profile.key3 == "stillfun")
38 |
39 | local ns2 = db:GetNamespace("test")
40 | assert(namespace == ns2)
41 | end
42 |
43 | do
44 | local dbtbl = {}
45 | local db = LibStub("AceDB-3.0"):New(dbtbl, nil, "bar")
46 | local ns = db:RegisterNamespace("ns1")
47 |
48 | db.profile.foo = "bar"
49 | db:SetProfile("foo")
50 |
51 | WoWAPI_FireEvent("PLAYER_LOGOUT")
52 |
53 | local db = LibStub("AceDB-3.0"):New(dbtbl, nil, "foo")
54 | local ns = db:RegisterNamespace("ns1")
55 |
56 | db:DeleteProfile("bar")
57 | end
58 |
--------------------------------------------------------------------------------
/tests/AceDB-3.0-callbacks.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceDB-3.0/AceDB-3.0.lua")
5 | dofile("serialize.lua")
6 |
7 | -- Test OnProfileChanged
8 | do
9 | local testdb = LibStub("AceDB-3.0"):New({})
10 |
11 | local triggers = {}
12 |
13 | local function OnCallback(message, db, ...)
14 | if db == testdb then
15 | if message == "OnProfileChanged" then
16 | local profile = ...
17 | assert(profile == "Healers" or profile == "Tanks")
18 | elseif message == "OnProfileDeleted" then
19 | local profile = ...
20 | assert(profile == "Healers")
21 | elseif message == "OnProfileCopied" then
22 | local profile = ...
23 | assert(profile == "Healers")
24 | elseif message == "OnNewProfile" then
25 | local profile = ...
26 | assert(profile == "Healers" or profile == "Tanks")
27 | end
28 | triggers[message] = triggers[message] and triggers[message] + 1 or 1
29 | end
30 | end
31 |
32 | testdb:RegisterCallback("OnProfileChanged", OnCallback)
33 | testdb:RegisterCallback("OnProfileDeleted", OnCallback)
34 | testdb:RegisterCallback("OnProfileCopied", OnCallback)
35 | testdb:RegisterCallback("OnDatabaseReset", OnCallback)
36 | testdb:RegisterCallback("OnNewProfile", OnCallback)
37 | testdb:ResetDB("Healers")
38 | testdb:SetProfile("Tanks")
39 | testdb:CopyProfile("Healers")
40 | testdb:DeleteProfile("Healers")
41 | assert(triggers.OnProfileChanged == 2)
42 | assert(triggers.OnDatabaseReset == 1)
43 | assert(triggers.OnProfileDeleted == 1)
44 | assert(triggers.OnProfileCopied == 1)
45 | assert(triggers.OnNewProfile == 2)
46 | end
47 |
48 | do
49 | local dbDefaults = {
50 | profile = { bla = 0, },
51 | }
52 | local db = LibStub("AceDB-3.0"):New({}, dbDefaults, true)
53 | db:RegisterCallback("OnNewProfile", function()
54 | db.profile.bla = 1
55 | end)
56 | db:SetProfile("blatest")
57 | assert(db.profile.bla == 1)
58 | end
59 |
--------------------------------------------------------------------------------
/tests/AceTimer-3.0-test3.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 |
4 | local MAJOR = "AceTimer-3.0"
5 |
6 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
7 |
8 | local AceTimer,minor = LibStub:GetLibrary(MAJOR)
9 |
10 |
11 | ---- test all methods of registration: anonymous funcs, member func names, etc etc
12 |
13 |
14 | local function func(arg)
15 | assert(arg=="t1s" or arg=="t2s" or arg=="t3s" or arg=="t4s")
16 | assert(_G[arg]==nil or type(_G[arg])=="number", dump(arg,type(_G[arg])))
17 | _G[arg]=(_G[arg] or 0)+1
18 | end
19 |
20 | -- Completely anonymous timer
21 | local t1 = AceTimer:ScheduleRepeatingTimer(func, 1, "t1s")
22 |
23 | -- Timer associated to a table
24 | local obj2={}
25 | local t2 = AceTimer.ScheduleRepeatingTimer(obj2, func, 1, "t2s")
26 |
27 | -- Member function on a table
28 | local obj3={}
29 | function obj3:func(arg)
30 | assert(self==obj3 and arg=="oogabooga")
31 | func("t3s")
32 | end
33 | local t3 = AceTimer.ScheduleRepeatingTimer(obj3, "func", 1, "oogabooga")
34 |
35 | -- Timer associated to a string
36 | local t4 = AceTimer.ScheduleRepeatingTimer("me4", func, 1, "t4s")
37 |
38 |
39 |
40 | WoWAPI_FireUpdate(0)
41 | assert(t1s==nil and t2s==nil and t3s==nil and t4s==nil, dump(t1s,t2s,t3s,t4s))
42 |
43 | WoWAPI_FireUpdate(1)
44 | assert(t1s==1 and t2s==1 and t3s==1 and t4s==1, dump(t1s,t2s,t3s,t4s))
45 |
46 | AceTimer.CancelAllTimers(obj2)
47 |
48 | WoWAPI_FireUpdate(2)
49 | assert(t1s==2 and t2s==1 and t3s==2 and t4s==2, dump(t1s,t2s,t3s,t4s))
50 |
51 | AceTimer.CancelAllTimers(obj3)
52 |
53 | WoWAPI_FireUpdate(3)
54 | assert(t1s==3 and t2s==1 and t3s==2 and t4s==3, dump(t1s,t2s,t3s,t4s))
55 |
56 | AceTimer.CancelAllTimers("me4")
57 |
58 | WoWAPI_FireUpdate(4)
59 | assert(t1s==4 and t2s==1 and t3s==2 and t4s==3, dump(t1s,t2s,t3s,t4s))
60 |
61 | AceTimer:CancelTimer(t1)
62 |
63 | WoWAPI_FireUpdate(5)
64 | assert(t1s==4 and t2s==1 and t3s==2 and t4s==3, dump(t1s,t2s,t3s,t4s))
65 |
66 |
67 |
68 | -----------------------------------------------------------------------
69 | print "OK"
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | SimpleGroup Container
3 | Simple container widget that just groups widgets.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "SimpleGroup", 20
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Methods
18 | -------------------------------------------------------------------------------]]
19 | local methods = {
20 | ["OnAcquire"] = function(self)
21 | self:SetWidth(300)
22 | self:SetHeight(100)
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["LayoutFinished"] = function(self, width, height)
28 | if self.noAutoHeight then return end
29 | self:SetHeight(height or 0)
30 | end,
31 |
32 | ["OnWidthSet"] = function(self, width)
33 | local content = self.content
34 | content:SetWidth(width)
35 | content.width = width
36 | end,
37 |
38 | ["OnHeightSet"] = function(self, height)
39 | local content = self.content
40 | content:SetHeight(height)
41 | content.height = height
42 | end
43 | }
44 |
45 | --[[-----------------------------------------------------------------------------
46 | Constructor
47 | -------------------------------------------------------------------------------]]
48 | local function Constructor()
49 | local frame = CreateFrame("Frame", nil, UIParent)
50 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
51 |
52 | --Container Support
53 | local content = CreateFrame("Frame", nil, frame)
54 | content:SetPoint("TOPLEFT")
55 | content:SetPoint("BOTTOMRIGHT")
56 |
57 | local widget = {
58 | frame = frame,
59 | content = content,
60 | type = Type
61 | }
62 | for method, func in pairs(methods) do
63 | widget[method] = func
64 | end
65 |
66 | return AceGUI:RegisterAsContainer(widget)
67 | end
68 |
69 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
70 |
--------------------------------------------------------------------------------
/AceConfig-3.0/AceConfig-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceConfig-3.0 wrapper library.
2 | -- Provides an API to register an options table with the config registry,
3 | -- as well as associate it with a slash command.
4 | -- @class file
5 | -- @name AceConfig-3.0
6 | -- @release $Id$
7 |
8 | --[[
9 | AceConfig-3.0
10 |
11 | Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
12 |
13 | ]]
14 |
15 | local cfgreg = LibStub("AceConfigRegistry-3.0")
16 | local cfgcmd = LibStub("AceConfigCmd-3.0")
17 |
18 | local MAJOR, MINOR = "AceConfig-3.0", 3
19 | local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
20 |
21 | if not AceConfig then return end
22 |
23 | --TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
24 | --TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
25 |
26 | -- Lua APIs
27 | local pcall, error, type, pairs = pcall, error, type, pairs
28 |
29 | -- -------------------------------------------------------------------
30 | -- :RegisterOptionsTable(appName, options, slashcmd)
31 | --
32 | -- - appName - (string) application name
33 | -- - options - table or function ref, see AceConfigRegistry
34 | -- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
35 |
36 | --- Register a option table with the AceConfig registry.
37 | -- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
38 | -- @paramsig appName, options [, slashcmd]
39 | -- @param appName The application name for the config table.
40 | -- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
41 | -- @param slashcmd A slash command to register for the option table, or a table of slash commands.
42 | -- @usage
43 | -- local AceConfig = LibStub("AceConfig-3.0")
44 | -- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
45 | function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
46 | local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
47 | if not ok then error(msg, 2) end
48 |
49 | if slashcmd then
50 | if type(slashcmd) == "table" then
51 | for _,cmd in pairs(slashcmd) do
52 | cfgcmd:CreateChatCommand(cmd, appName)
53 | end
54 | else
55 | cfgcmd:CreateChatCommand(slashcmd, appName)
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/tests/LibStub.lua:
--------------------------------------------------------------------------------
1 | -- $Id: LibStub.lua 48018 2007-09-03 01:50:17Z mikk $
2 | -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
3 | -- LibStub is hereby placed in the Public Domain
4 | -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
5 | local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
6 | local LibStub = _G[LIBSTUB_MAJOR]
7 |
8 | -- Check to see is this version of the stub is obsolete
9 | if not LibStub or LibStub.minor < LIBSTUB_MINOR then
10 | LibStub = LibStub or {libs = {}, minors = {} }
11 | _G[LIBSTUB_MAJOR] = LibStub
12 | LibStub.minor = LIBSTUB_MINOR
13 |
14 | -- LibStub:NewLibrary(major, minor)
15 | -- major (string) - the major version of the library
16 | -- minor (string or number ) - the minor version of the library
17 | --
18 | -- returns nil if a newer or same version of the lib is already present
19 | -- returns empty library object or old library object if upgrade is needed
20 | function LibStub:NewLibrary(major, minor)
21 | assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
22 | minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
23 |
24 | local oldminor = self.minors[major]
25 | if oldminor and oldminor >= minor then return nil end
26 | self.minors[major], self.libs[major] = minor, self.libs[major] or {}
27 | return self.libs[major], oldminor
28 | end
29 |
30 | -- LibStub:GetLibrary(major, [silent])
31 | -- major (string) - the major version of the library
32 | -- silent (boolean) - if true, library is optional, silently return nil if its not found
33 | --
34 | -- throws an error if the library can not be found (except silent is set)
35 | -- returns the library object if found
36 | function LibStub:GetLibrary(major, silent)
37 | if not self.libs[major] and not silent then
38 | error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
39 | end
40 | return self.libs[major], self.minors[major]
41 | end
42 |
43 | -- LibStub:IterateLibraries()
44 | --
45 | -- Returns an iterator for the currently registered libraries
46 | function LibStub:IterateLibraries()
47 | return pairs(self.libs)
48 | end
49 |
50 | setmetatable(LibStub, { __call = LibStub.GetLibrary })
51 | end
52 |
--------------------------------------------------------------------------------
/.luacheckrc:
--------------------------------------------------------------------------------
1 | std = "lua51"
2 | max_line_length = false
3 | exclude_files = {
4 | "tests/",
5 | ".luacheckrc"
6 | }
7 |
8 | ignore = {
9 | "11./BINDING_.*", -- Setting an undefined (Keybinding) global variable
10 | "211", -- Unused local variable
11 | "212", -- Unused argument
12 | "213", -- Unused loop variable
13 | "542", -- empty if branch
14 | }
15 |
16 | globals = {
17 | "Ace3",
18 | "ChatThrottleLib",
19 |
20 | "AceGUIEditBoxInsertLink",
21 | "AceGUIMultiLineEditBoxInsertLink",
22 | "ChatEdit_CustomTabPressed",
23 | "CloseSpecialWindows",
24 | "ColorPickerFrame",
25 | "SlashCmdList", "hash_SlashCmdList",
26 | }
27 |
28 | read_globals = {
29 | "geterrorhandler",
30 | "securecallfunction",
31 | "table", "string",
32 |
33 | "LibStub",
34 |
35 | -- WoW API
36 | "Ambiguate",
37 | "C_ChatInfo",
38 | "C_SettingsUtil",
39 | "C_Spell",
40 | "C_Timer",
41 | "ClearCursor",
42 | "CreateFont",
43 | "CreateFrame",
44 | "Enum.SendAddonMessageResult",
45 | "GetCurrentRegion",
46 | "GetCurrentRegionName",
47 | "GetCursorInfo",
48 | "GetFramerate",
49 | "GetLocale",
50 | "GetMacroInfo",
51 | "GetRealmName",
52 | "GetSpellInfo",
53 | "GetTime",
54 | "hooksecurefunc",
55 | "InCombatLockdown",
56 | "issecurevariable",
57 | "IsAltKeyDown",
58 | "IsControlKeyDown",
59 | "IsLoggedIn",
60 | "IsShiftKeyDown",
61 | "PlaySound",
62 | "RegisterAddonMessagePrefix",
63 | "ReloadUI",
64 | "UnitClass",
65 | "UnitFactionGroup",
66 | "UnitInParty",
67 | "UnitInRaid",
68 | "UnitName",
69 | "UnitRace",
70 |
71 | -- FrameXML API
72 | "ChatEdit_GetActiveWindow",
73 | "ChatEdit_InsertLink",
74 | "ChatFrameUtil",
75 | "InterfaceOptions_AddCategory",
76 | "IsSecureCmd",
77 | "SetDesaturation",
78 | "Settings",
79 |
80 | -- FrameXML Frames & Constants
81 | "ACCEPT",
82 | "CANCEL",
83 | "ChatFontNormal",
84 | "CLOSE",
85 | "DEFAULT_CHAT_FRAME",
86 | "FONT_COLOR_CODE_CLOSE",
87 | "GameFontDisableSmall",
88 | "GameFontHighlight",
89 | "GameFontHighlightLarge",
90 | "GameFontHighlightSmall",
91 | "GameFontNormal",
92 | "GameFontNormalSmall",
93 | "GameTooltip",
94 | "InterfaceOptionsFramePanelContainer",
95 | "NORMAL_FONT_COLOR",
96 | "NORMAL_FONT_COLOR_CODE",
97 | "NOT_BOUND",
98 | "NUM_CHAT_WINDOWS",
99 | "OKAY",
100 | "OpacitySliderFrame",
101 | "SELECTED_CHAT_FRAME",
102 | "UIParent",
103 | "WOW_PROJECT_ID",
104 | "WOW_PROJECT_MAINLINE",
105 |
106 | -- Custom Globals
107 | "GAME_LOCALE",
108 | }
109 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Heading Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Heading", 20
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Methods
16 | -------------------------------------------------------------------------------]]
17 | local methods = {
18 | ["OnAcquire"] = function(self)
19 | self:SetText()
20 | self:SetFullWidth()
21 | self:SetHeight(18)
22 | end,
23 |
24 | -- ["OnRelease"] = nil,
25 |
26 | ["SetText"] = function(self, text)
27 | self.label:SetText(text or "")
28 | if text and text ~= "" then
29 | self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
30 | self.right:Show()
31 | else
32 | self.left:SetPoint("RIGHT", -3, 0)
33 | self.right:Hide()
34 | end
35 | end
36 | }
37 |
38 | --[[-----------------------------------------------------------------------------
39 | Constructor
40 | -------------------------------------------------------------------------------]]
41 | local function Constructor()
42 | local frame = CreateFrame("Frame", nil, UIParent)
43 | frame:Hide()
44 |
45 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
46 | label:SetPoint("TOP")
47 | label:SetPoint("BOTTOM")
48 | label:SetJustifyH("CENTER")
49 |
50 | local left = frame:CreateTexture(nil, "BACKGROUND")
51 | left:SetHeight(8)
52 | left:SetPoint("LEFT", 3, 0)
53 | left:SetPoint("RIGHT", label, "LEFT", -5, 0)
54 | left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
55 | left:SetTexCoord(0.81, 0.94, 0.5, 1)
56 |
57 | local right = frame:CreateTexture(nil, "BACKGROUND")
58 | right:SetHeight(8)
59 | right:SetPoint("RIGHT", -3, 0)
60 | right:SetPoint("LEFT", label, "RIGHT", 5, 0)
61 | right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
62 | right:SetTexCoord(0.81, 0.94, 0.5, 1)
63 |
64 | local widget = {
65 | label = label,
66 | left = left,
67 | right = right,
68 | frame = frame,
69 | type = Type
70 | }
71 | for method, func in pairs(methods) do
72 | widget[method] = func
73 | end
74 |
75 | return AceGUI:RegisterAsWidget(widget)
76 | end
77 |
78 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
79 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InteractiveLabel Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "InteractiveLabel", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs = select, pairs
10 |
11 | --[[-----------------------------------------------------------------------------
12 | Scripts
13 | -------------------------------------------------------------------------------]]
14 | local function Control_OnEnter(frame)
15 | frame.obj:Fire("OnEnter")
16 | end
17 |
18 | local function Control_OnLeave(frame)
19 | frame.obj:Fire("OnLeave")
20 | end
21 |
22 | local function Label_OnClick(frame, button)
23 | frame.obj:Fire("OnClick", button)
24 | AceGUI:ClearFocus()
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Methods
29 | -------------------------------------------------------------------------------]]
30 | local methods = {
31 | ["OnAcquire"] = function(self)
32 | self:LabelOnAcquire()
33 | self:SetHighlight()
34 | self:SetHighlightTexCoord()
35 | self:SetDisabled(false)
36 | end,
37 |
38 | -- ["OnRelease"] = nil,
39 |
40 | ["SetHighlight"] = function(self, ...)
41 | self.highlight:SetTexture(...)
42 | end,
43 |
44 | ["SetHighlightTexCoord"] = function(self, ...)
45 | local c = select("#", ...)
46 | if c == 4 or c == 8 then
47 | self.highlight:SetTexCoord(...)
48 | else
49 | self.highlight:SetTexCoord(0, 1, 0, 1)
50 | end
51 | end,
52 |
53 | ["SetDisabled"] = function(self,disabled)
54 | self.disabled = disabled
55 | if disabled then
56 | self.frame:EnableMouse(false)
57 | self.label:SetTextColor(0.5, 0.5, 0.5)
58 | else
59 | self.frame:EnableMouse(true)
60 | self.label:SetTextColor(1, 1, 1)
61 | end
62 | end
63 | }
64 |
65 | --[[-----------------------------------------------------------------------------
66 | Constructor
67 | -------------------------------------------------------------------------------]]
68 | local function Constructor()
69 | -- create a Label type that we will hijack
70 | local label = AceGUI:Create("Label")
71 |
72 | local frame = label.frame
73 | frame:EnableMouse(true)
74 | frame:SetScript("OnEnter", Control_OnEnter)
75 | frame:SetScript("OnLeave", Control_OnLeave)
76 | frame:SetScript("OnMouseDown", Label_OnClick)
77 |
78 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
79 | highlight:SetTexture(nil)
80 | highlight:SetAllPoints()
81 | highlight:SetBlendMode("ADD")
82 |
83 | label.highlight = highlight
84 | label.type = Type
85 | label.LabelOnAcquire = label.OnAcquire
86 | for method, func in pairs(methods) do
87 | label[method] = func
88 | end
89 |
90 | return label
91 | end
92 |
93 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
94 |
95 |
--------------------------------------------------------------------------------
/tests/AceComm-3.0-callbacks.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("../LibStub/LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
5 | dofile("../AceComm-3.0/AceComm-3.0.lua")
6 |
7 |
8 |
9 | local AceComm = LibStub("AceComm-3.0")
10 |
11 | local addon1 = {}
12 |
13 | AceComm:Embed(addon1)
14 |
15 |
16 |
17 |
18 | -----------------------------------------------------------------------
19 | -----------------------------------------------------------------------
20 | -----------------------------------------------------------------------
21 | --
22 | -- Test callbacks firing delayed
23 | --
24 |
25 |
26 | -- Single message
27 |
28 | local nSingle=0
29 | addon1:SendCommMessage("single", "1234567890", "RAID", nil, "NORMAL",
30 | function(arg,sent,total)
31 | assert(arg=="singlearg")
32 | nSingle=nSingle+1
33 | assert(sent==10 and total==10)
34 | end,
35 | "singlearg"
36 | )
37 |
38 | -- Multipart message
39 | local nMulti=0
40 | addon1:SendCommMessage("multi", strrep("1234567890", 80), "RAID", nil, "NORMAL",
41 | function(arg,sent,total)
42 | assert(arg=="multiarg")
43 | nMulti=nMulti+1
44 | -- print(sent)
45 | if nMulti>=1 and nMulti<=3 then
46 | assert(sent==(255-1)*nMulti) -- 256 - \0 - \t - #prefix - [\001-\003]
47 | elseif nMulti==4 then
48 | assert(sent==800)
49 | end
50 | assert(total==800)
51 | end,
52 | "multiarg"
53 | )
54 |
55 | assert(nSingle==0)
56 | assert(nMulti==0)
57 |
58 | WoWAPI_FireUpdate(GetTime()+100) -- 100 seconds later
59 |
60 | assert(nSingle==1)
61 | assert(nMulti==4)
62 |
63 |
64 |
65 | -----------------------------------------------------------------------
66 | -----------------------------------------------------------------------
67 | -----------------------------------------------------------------------
68 | --
69 | -- Test callbacks firing IMMEDIATELY (recursively)
70 | --
71 |
72 | WoWAPI_FireUpdate(GetTime()+100) -- 100 seconds later
73 |
74 |
75 | -- Single message
76 |
77 | local nSingle=0
78 | addon1:SendCommMessage("single", "1234567890", "RAID", nil, "NORMAL",
79 | function(arg,sent,total)
80 | assert(arg=="singlearg")
81 | nSingle=nSingle+1
82 | assert(sent==10 and total==10)
83 | end,
84 | "singlearg"
85 | )
86 | assert(nSingle==1)
87 |
88 |
89 | -- Multipart message
90 | local nMulti=0
91 | addon1:SendCommMessage("multi", strrep("1234567890", 80), "RAID", nil, "NORMAL",
92 | function(arg,sent,total)
93 | assert(arg=="multiarg")
94 | nMulti=nMulti+1
95 | -- print(sent)
96 | if nMulti>=1 and nMulti<=3 then
97 | assert(sent==(255-1)*nMulti) -- 256 - \0 - \t - #prefix - [\001-\003]
98 | elseif nMulti==4 then
99 | assert(sent==800)
100 | end
101 | assert(total==800)
102 | end,
103 | "multiarg"
104 | )
105 |
106 | assert(nMulti==4)
107 |
108 | WoWAPI_FireUpdate(time()+100) -- 100 seconds later
109 |
110 | assert(nSingle==1)
111 | assert(nMulti==4)
112 |
113 |
114 |
115 |
116 |
117 | -----------------------------------------------------------------------
118 | print "OK"
119 |
--------------------------------------------------------------------------------
/Ace3.lua:
--------------------------------------------------------------------------------
1 |
2 | -- This file is only there in standalone Ace3 and provides handy dev tool stuff I guess
3 | -- for now only /rl to reload your UI :)
4 | -- note the complete overkill use of AceAddon and console, ain't it cool?
5 |
6 | -- GLOBALS: next, loadstring, ReloadUI, geterrorhandler
7 | -- GLOBALS: BINDING_HEADER_ACE3, BINDING_NAME_RELOADUI, Ace3, LibStub
8 |
9 | -- BINDINGs labels
10 | BINDING_HEADER_ACE3 = "Ace3"
11 | BINDING_NAME_RELOADUI = "ReloadUI"
12 | --
13 |
14 | local gui = LibStub("AceGUI-3.0")
15 | local reg = LibStub("AceConfigRegistry-3.0")
16 | local dialog = LibStub("AceConfigDialog-3.0")
17 |
18 | Ace3 = LibStub("AceAddon-3.0"):NewAddon("Ace3", "AceConsole-3.0")
19 | local Ace3 = Ace3
20 |
21 | local selectedgroup
22 | local frame
23 | local select
24 | local status = {}
25 | local configs = {}
26 |
27 | local function frameOnClose()
28 | gui:Release(frame)
29 | frame = nil
30 | end
31 |
32 | local function RefreshConfigs()
33 | for name in reg:IterateOptionsTables() do
34 | configs[name] = name
35 | end
36 | end
37 |
38 | local function ConfigSelected(widget, event, value)
39 | selectedgroup = value
40 | dialog:Open(value, widget)
41 | end
42 |
43 | local old_CloseSpecialWindows
44 |
45 | -- GLOBALS: CloseSpecialWindows, next
46 | function Ace3:Open()
47 | if not old_CloseSpecialWindows then
48 | old_CloseSpecialWindows = CloseSpecialWindows
49 | CloseSpecialWindows = function()
50 | local found = old_CloseSpecialWindows()
51 | if frame then
52 | frame:Hide()
53 | return true
54 | end
55 | return found
56 | end
57 | end
58 | RefreshConfigs()
59 | if next(configs) == nil then
60 | self:Print("No Configs are Registered")
61 | return
62 | end
63 |
64 | if not frame then
65 | frame = gui:Create("Frame")
66 | frame:ReleaseChildren()
67 | frame:SetTitle("Ace3 Options")
68 | frame:SetLayout("FILL")
69 | frame:SetCallback("OnClose", frameOnClose)
70 |
71 | select = gui:Create("DropdownGroup")
72 | select:SetGroupList(configs)
73 | select:SetCallback("OnGroupSelected", ConfigSelected)
74 | frame:AddChild(select)
75 | end
76 | if not selectedgroup then
77 | selectedgroup = next(configs)
78 | end
79 | select:SetGroup(selectedgroup)
80 | frame:Show()
81 | end
82 |
83 | local function RefreshOnUpdate(this)
84 | select:SetGroup(selectedgroup)
85 | this:SetScript("OnUpdate", nil)
86 | end
87 |
88 | function Ace3:ConfigTableChanged(event, appName)
89 | if selectedgroup == appName and frame then
90 | frame.frame:SetScript("OnUpdate", RefreshOnUpdate)
91 | end
92 | end
93 |
94 | reg.RegisterCallback(Ace3, "ConfigTableChange", "ConfigTableChanged")
95 |
96 | function Ace3:PrintCmd(input)
97 | input = input:trim():match("^(.-);*$")
98 | local func, err = loadstring("LibStub(\"AceConsole-3.0\"):Print(" .. input .. ")")
99 | if not func then
100 | LibStub("AceConsole-3.0"):Print("Error: " .. err)
101 | else
102 | func()
103 | end
104 | end
105 |
106 | function Ace3:OnInitialize()
107 | self:RegisterChatCommand("ace3", function() self:Open() end)
108 | self:RegisterChatCommand("rl", function() ReloadUI() end)
109 | self:RegisterChatCommand("print", "PrintCmd")
110 | end
111 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-Button.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Button Widget
3 | Graphical Button.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Button", 24
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local _G = _G
14 | local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 | local function Button_OnClick(frame, ...)
20 | AceGUI:ClearFocus()
21 | PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
22 | frame.obj:Fire("OnClick", ...)
23 | end
24 |
25 | local function Control_OnEnter(frame)
26 | frame.obj:Fire("OnEnter")
27 | end
28 |
29 | local function Control_OnLeave(frame)
30 | frame.obj:Fire("OnLeave")
31 | end
32 |
33 | --[[-----------------------------------------------------------------------------
34 | Methods
35 | -------------------------------------------------------------------------------]]
36 | local methods = {
37 | ["OnAcquire"] = function(self)
38 | -- restore default values
39 | self:SetHeight(24)
40 | self:SetWidth(200)
41 | self:SetDisabled(false)
42 | self:SetAutoWidth(false)
43 | self:SetText()
44 | end,
45 |
46 | -- ["OnRelease"] = nil,
47 |
48 | ["SetText"] = function(self, text)
49 | self.text:SetText(text)
50 | if self.autoWidth then
51 | self:SetWidth(self.text:GetStringWidth() + 30)
52 | end
53 | end,
54 |
55 | ["SetAutoWidth"] = function(self, autoWidth)
56 | self.autoWidth = autoWidth
57 | if self.autoWidth then
58 | self:SetWidth(self.text:GetStringWidth() + 30)
59 | end
60 | end,
61 |
62 | ["SetDisabled"] = function(self, disabled)
63 | self.disabled = disabled
64 | if disabled then
65 | self.frame:Disable()
66 | else
67 | self.frame:Enable()
68 | end
69 | end
70 | }
71 |
72 | --[[-----------------------------------------------------------------------------
73 | Constructor
74 | -------------------------------------------------------------------------------]]
75 | local function Constructor()
76 | local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
77 | local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
78 | frame:Hide()
79 |
80 | frame:EnableMouse(true)
81 | frame:SetScript("OnClick", Button_OnClick)
82 | frame:SetScript("OnEnter", Control_OnEnter)
83 | frame:SetScript("OnLeave", Control_OnLeave)
84 |
85 | local text = frame:GetFontString()
86 | text:ClearAllPoints()
87 | text:SetPoint("TOPLEFT", 15, -1)
88 | text:SetPoint("BOTTOMRIGHT", -15, 1)
89 | text:SetJustifyV("MIDDLE")
90 |
91 | local widget = {
92 | text = text,
93 | frame = frame,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsWidget(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/tests/AceAddon-3.0.lua:
--------------------------------------------------------------------------------
1 | -- TODO:
2 | -- Test module support of AceAddon-3.0.
3 |
4 |
5 |
6 | dofile("wow_api.lua")
7 | dofile("LibStub.lua")
8 | dofile("../AceAddon-3.0/AceAddon-3.0.lua")
9 |
10 | local AceAddon = LibStub("AceAddon-3.0")
11 |
12 | do -- Test create addon.
13 |
14 | local success, reason, addon
15 |
16 | -- 'name' - string expected
17 | success, reason = pcall( function() AceAddon:NewAddon() end )
18 | assert( success == false and reason:find("'name' - string expected",1,true) )
19 |
20 | -- Cannot find a library instance of "Testing123".
21 | success, reason = pcall( function() AceAddon:NewAddon("TestAddon-1", "Testing123") end )
22 | assert( success == false and reason:find("Cannot find a library instance",1,true) )
23 |
24 | -- Success.
25 | addon = AceAddon:NewAddon("TestAddon-2")
26 | assert( addon and addon == AceAddon:GetAddon("TestAddon-2") )
27 |
28 | -- Addon 'TestAddon-2' already exists.
29 | success, reason = pcall( function() addon = AceAddon:NewAddon("TestAddon-2") end )
30 | assert( success == false and reason:find("Addon 'TestAddon-2' already exists",1,true) )
31 |
32 | end
33 |
34 |
35 |
36 | do -- Test mixin.
37 |
38 | -- Define a simple library for testing mixin.
39 | local libA = LibStub:NewLibrary("LibStupid",1)
40 | if libA then
41 | libA.mixins = { "BecomeStupid", "BecomeDumb" }
42 | function libA:BecomeStupid()
43 | end
44 | function libA:BecomeDumb()
45 | end
46 | function libA:Embed(target)
47 | for i,method in ipairs(self.mixins) do
48 | target[method] = self[method]
49 | end
50 | end
51 | end
52 |
53 | -- Yet another library.
54 | local libB = LibStub:NewLibrary("LibSmart",1)
55 | if libB then
56 | libB.mixins = { "BecomeSmart", "BecomeClever" }
57 | function libB:BecomeSmart()
58 | end
59 | function libB:BecomeClever()
60 | end
61 | function libB:Embed(target)
62 | for i,method in ipairs(self.mixins) do
63 | target[method] = self[method]
64 | end
65 | end
66 | end
67 |
68 | -- Create an AceAddon object with 2 libraries mixed.
69 | local addon = AceAddon:NewAddon("TestAddon-3","LibStupid","LibSmart")
70 |
71 | -- Are the methods mixed correctly?
72 | assert( addon.BecomeStupid == libA.BecomeStupid )
73 | assert( addon.BecomeDumb == libA.BecomeDumb )
74 | assert( addon.BecomeSmart == libB.BecomeSmart )
75 | assert( addon.BecomeClever == libB.BecomeClever )
76 | end
77 |
78 |
79 | do -- Test the call to OnInitialize, OnEnable and OnDisable.
80 |
81 | local addon = AceAddon:NewAddon("TestAddon-4","LibStupid","LibSmart")
82 |
83 | local initialized = false
84 | function addon:OnInitialize()
85 | initialized = true
86 | end
87 |
88 | local enabled = false
89 | function addon:OnEnable()
90 | enabled = true
91 | end
92 |
93 | function addon:OnDisable()
94 | enabled = false
95 | end
96 |
97 | -- Testing the call to addon:OnInitialize().
98 | WoWAPI_FireEvent("ADDON_LOADED",ADDON_NAME)
99 | assert(initialized and not enabled)
100 |
101 | -- IsLoggedIn() is supposed to return true when addon receives PLAYER_LOGIN.
102 | function IsLoggedIn() return true end
103 |
104 | -- Testing the call to addon:OnEnable()
105 | WoWAPI_FireEvent("PLAYER_LOGIN")
106 | assert(initialized and enabled)
107 |
108 | -- Testing the call to addon:OnDisable()
109 | AceAddon:DisableAddon(addon)
110 | assert(initialized and not enabled)
111 |
112 | end
113 |
114 | print("Test finished.")
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InlineGroup Container
3 | Simple container widget that creates a visible "box" with an optional title.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "InlineGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Methods
17 | -------------------------------------------------------------------------------]]
18 | local methods = {
19 | ["OnAcquire"] = function(self)
20 | self:SetWidth(300)
21 | self:SetHeight(100)
22 | self:SetTitle("")
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["SetTitle"] = function(self,title)
28 | self.titletext:SetText(title)
29 | end,
30 |
31 |
32 | ["LayoutFinished"] = function(self, width, height)
33 | if self.noAutoHeight then return end
34 | self:SetHeight((height or 0) + 40)
35 | end,
36 |
37 | ["OnWidthSet"] = function(self, width)
38 | local content = self.content
39 | local contentwidth = width - 20
40 | if contentwidth < 0 then
41 | contentwidth = 0
42 | end
43 | content:SetWidth(contentwidth)
44 | content.width = contentwidth
45 | end,
46 |
47 | ["OnHeightSet"] = function(self, height)
48 | local content = self.content
49 | local contentheight = height - 20
50 | if contentheight < 0 then
51 | contentheight = 0
52 | end
53 | content:SetHeight(contentheight)
54 | content.height = contentheight
55 | end
56 | }
57 |
58 | --[[-----------------------------------------------------------------------------
59 | Constructor
60 | -------------------------------------------------------------------------------]]
61 | local PaneBackdrop = {
62 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
63 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
64 | tile = true, tileSize = 16, edgeSize = 16,
65 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
66 | }
67 |
68 | local function Constructor()
69 | local frame = CreateFrame("Frame", nil, UIParent)
70 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
71 |
72 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
73 | titletext:SetPoint("TOPLEFT", 14, 0)
74 | titletext:SetPoint("TOPRIGHT", -14, 0)
75 | titletext:SetJustifyH("LEFT")
76 | titletext:SetHeight(18)
77 |
78 | local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
79 | border:SetPoint("TOPLEFT", 0, -17)
80 | border:SetPoint("BOTTOMRIGHT", -1, 3)
81 | border:SetBackdrop(PaneBackdrop)
82 | border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
83 | border:SetBackdropBorderColor(0.4, 0.4, 0.4)
84 |
85 | --Container Support
86 | local content = CreateFrame("Frame", nil, border)
87 | content:SetPoint("TOPLEFT", 10, -10)
88 | content:SetPoint("BOTTOMRIGHT", -10, 10)
89 |
90 | local widget = {
91 | frame = frame,
92 | content = content,
93 | titletext = titletext,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsContainer(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/tests/AceLocale-3.0.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../AceLocale-3.0/AceLocale-3.0.lua")
4 |
5 | local AceLocale = LibStub("AceLocale-3.0")
6 |
7 | local loc = AceLocale:NewLocale("test", "enUS")
8 | loc["a"] = "A"
9 | loc["c"] = "C"
10 |
11 | local loc = AceLocale:NewLocale("test", "deDE", true)
12 | loc["a"] = "aa"
13 | loc["b"] = "bb"
14 | loc["c"] = "cc"
15 |
16 | local loc = AceLocale:NewLocale("test", "frFR")
17 | assert(loc == nil)
18 |
19 |
20 | local test = AceLocale:GetLocale("test")
21 |
22 | assert(test["a"] == "A")
23 | assert(test["b"] == "bb")
24 | assert(test["c"] == "C")
25 |
26 | -- Test requesting an unknown string
27 | local oldgeterrorhandler = geterrorhandler
28 | local errors=0
29 | _G.geterrorhandler = function() return function() errors=errors+1 end end
30 | assert(test["thisdoesntexist"]=="thisdoesntexist")
31 | assert(errors==1)
32 | _G.geterrorhandler=oldgeterrorhandler
33 |
34 | ------------------------------------------------
35 | -- Test the silent flag working
36 |
37 | local loc = AceLocale:NewLocale("test2", "enUS", true, true) -- silent flag set on first locale to be registered
38 | loc["This Exists"]=true
39 | AceLocale:NewLocale("test2", "deDE")
40 | AceLocale:NewLocale("test2", "frFR")
41 |
42 | local test2=AceLocale:GetLocale("test2")
43 | assert(test2["thisdoesntexist"]=="thisdoesntexist")
44 | assert(test2["This Exists"]=="This Exists")
45 |
46 |
47 | ------------------------------------------------
48 | -- Test the silent flag working even if the default locale is registered second
49 |
50 | AceLocale:NewLocale("test3", "deDE", false, true) -- silent flag set on first locale to be registered
51 | AceLocale:NewLocale("test3", "enUS", true)
52 | AceLocale:NewLocale("test3", "frFR")
53 |
54 | local test3=AceLocale:GetLocale("test3")
55 | assert(test3["thisdoesntexist"]=="thisdoesntexist")
56 | assert(test3["This Exists"]=="This Exists")
57 |
58 |
59 | ------------------------------------------------
60 | -- Test the silent flag warning when using it on nonfirst
61 |
62 | local oldgeterrorhandler = geterrorhandler
63 | local errors=0
64 | _G.geterrorhandler = function() return function() errors=errors+1 end end
65 |
66 | AceLocale:NewLocale("test3a", "deDE")
67 | AceLocale:NewLocale("test3a", "enUS", true, true)
68 | AceLocale:NewLocale("test3a", "frFR")
69 |
70 | assert(errors==1)
71 | _G.geterrorhandler=oldgeterrorhandler
72 |
73 |
74 | ------------------------------------------------
75 | -- Test silent="raw" working
76 |
77 | local loc = AceLocale:NewLocale("test4", "enUS", true, "raw")
78 | loc["This Exists"]=true
79 | AceLocale:NewLocale("test4", "deDE")
80 | AceLocale:NewLocale("test4", "frFR")
81 |
82 | local test4=AceLocale:GetLocale("test4")
83 | assert(test4["thisdoesntexist"]==nil)
84 | assert(test4["This Exists"]=="This Exists")
85 |
86 |
87 | ------------------------------------------------
88 | -- Test that we can re-get an already-created locale so we can write more to it
89 |
90 | local loc = AceLocale:NewLocale("test5", "enUS")
91 | loc["orig1"]=true
92 | loc["orig2"]="orig2"
93 | loc["orig3"]=true
94 | loc["orig4"]="orig4"
95 |
96 | local loc = AceLocale:NewLocale("unrelatedLocale", "enUS") -- touch something else in between to make extra sure
97 |
98 | local loc = AceLocale:NewLocale("test5", "enUS")
99 | loc["orig3"]="NEWorig3"
100 | loc["orig4"]="NEWorig4"
101 | loc["orig5"]="thisneverexisted"
102 |
103 | local test5=AceLocale:GetLocale("test5")
104 | assert(test5["orig1"]=="orig1")
105 | assert(test5["orig2"]=="orig2")
106 | assert(test5["orig3"]=="NEWorig3")
107 | assert(test5["orig4"]=="NEWorig4")
108 | assert(test5["orig5"]=="thisneverexisted")
109 |
110 |
111 | ------------------------------------------------
112 | print "OK"
113 |
--------------------------------------------------------------------------------
/tests/AceConfigCmd-3.0-ordering.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceConsole-3.0/AceConsole-3.0.lua")
5 | dofile("../AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua")
6 | dofile("../AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua")
7 |
8 | local ccmd = assert(LibStub("AceConfigCmd-3.0"))
9 | local creg = assert(LibStub("AceConfigRegistry-3.0"))
10 |
11 |
12 | local app={}
13 |
14 |
15 | ---------------- the option table!!
16 |
17 | local opts = {
18 | type = "group",
19 | get = function() end,
20 | set = function() end,
21 |
22 | args = {
23 | first = {
24 | type="toggle",
25 | name="1",
26 | order=1
27 | },
28 | second = {
29 | type="toggle",
30 | name="2",
31 | order=2
32 | },
33 | plugcmd = { -- this should never be used, we should use the plugin!
34 | name="PlugCmdOrig",
35 | desc="YOU SHOULD NOT SEE THIS",
36 | type="toggle",
37 | },
38 | inlinegroup = {
39 | order=70,
40 | name="inlinegroup",
41 | desc="An inline group",
42 | type="group",
43 | inline=false,
44 | cmdInline=true, -- test that cmdInline overrides inline
45 | args = {
46 | inline1 = {
47 | type="toggle",
48 | name="inline1",
49 | order=11,
50 | },
51 | inline2 = {
52 | type="toggle",
53 | name="inline2",
54 | order=12,
55 | },
56 | ininlinegroup = {
57 | order=1,
58 | name="ininlinegroup",
59 | desc="An inline inline group",
60 | type="group",
61 | inline=true,
62 | args = {
63 | ininline1 = {
64 | type="toggle",
65 | name="ininline1",
66 | }
67 | }
68 | }
69 | },
70 | },
71 | unset1 = {
72 | type="toggle",
73 | name="unset1",
74 | },
75 | unset2 = {
76 | type="toggle",
77 | name="unset2",
78 | },
79 | unset3 = {
80 | type="toggle",
81 | name="unset3",
82 | },
83 | afterunset = {
84 | type="toggle",
85 | name="101",
86 | order=101
87 | },
88 | last1 = {
89 | type="toggle",
90 | name="-1",
91 | order=-1,
92 | },
93 | last2 = {
94 | type="toggle",
95 | name="-2",
96 | order=-2,
97 | },
98 | last3 = {
99 | type="toggle",
100 | name="-3",
101 | order=-3,
102 | },
103 | last4 = {
104 | type="toggle",
105 | name="-4",
106 | order=-4,
107 | },
108 | },
109 |
110 | plugins = { -- test plugins
111 | plugin1 = {
112 | plugcmd = {
113 | name="50",
114 | type="toggle",
115 | order=50
116 | },
117 | plugcmd2 = {
118 | name="52",
119 | type="toggle",
120 | order=52
121 | }
122 | },
123 | plugin2 = {
124 | -- empty, shouldnt cause errors
125 | },
126 | plugin3 = {
127 | p3cmd = {
128 | name="51",
129 | type="toggle",
130 | order=51,
131 | },
132 | }
133 |
134 | }
135 | }
136 |
137 | creg:RegisterOptionsTable("testapp", opts)
138 |
139 |
140 |
141 | local output = {
142 | "Arguments to", -- header
143 | "first",
144 | "second",
145 | "plugcmd.*50",
146 | "p3cmd",
147 | "plugcmd2",
148 | "An inline group",
149 | "An inline inline group",
150 | "ininline1",
151 | "inline1",
152 | "inline2",
153 | "unset1",
154 | "unset2",
155 | "unset3",
156 | "afterunset",
157 | "last4",
158 | "last3",
159 | "last2",
160 | "last1"
161 | }
162 |
163 | function ChatFrame1.AddMessage(self, txt)
164 | -- print("> "..txt)
165 | local str = assert(tremove(output, 1))
166 | assert(string.match(txt, str), "Expected <"..str.."> got <"..txt..">")
167 | end
168 |
169 | ccmd:HandleCommand("test","testapp","")
170 |
171 | assert(not next(output), "we didnt get all the output we expected!")
172 |
173 |
174 | -----------------------------------------------------------------------
175 | print "OK"
176 |
--------------------------------------------------------------------------------
/tests/ChatThrottleLib-callbackerrors.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
3 |
4 |
5 |
6 |
7 | -- Test errors in CTL callbacks - messages should still be delivered!
8 | do
9 | WoWAPI_FireUpdate(0) -- 0 o'clock
10 |
11 | local frame=CreateFrame("Frame")
12 | frame:RegisterEvent("CHAT_MSG_ADDON")
13 |
14 | -- Queue 2 messages in sequence. They should pop out at different times
15 |
16 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg1", "SAY", nil, nil,
17 | function() error("test error 1") end
18 | )
19 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg2", "SAY", nil, nil,
20 | function() error("test error 2") end
21 | )
22 |
23 | local n=0
24 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
25 | assert(msg=="msg1")
26 | n=n+1
27 | end)
28 |
29 | local ok,msg = pcall(WoWAPI_FireUpdate,1) -- 1 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
30 | assert(not ok)
31 | assert(strmatch(msg,"test error 1"), msg)
32 | assert(n==1)
33 |
34 | local ok,msg = pcall(WoWAPI_FireUpdate,1) -- 1 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
35 | assert(ok)
36 | assert(n==1) -- WE SHOULD NOT SEE ANOTHER MESSAGE YET
37 |
38 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
39 | assert(msg=="msg2")
40 | n=n+1
41 | end)
42 |
43 | local ok,msg = pcall(WoWAPI_FireUpdate,2) -- 2 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
44 | assert(not ok)
45 | assert(strmatch(msg,"test error 2"), msg)
46 | assert(n==2)
47 |
48 |
49 | -- Now queue 2 messages up and hop 2 seconds into the future. (And pulse there twice)
50 |
51 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg3", "WHISPER", "target1", nil,
52 | function() error("test error 3") end
53 | )
54 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg4", "WHISPER", "target2", nil,
55 | function() error("test error 4") end
56 | )
57 |
58 |
59 |
60 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
61 | assert(msg=="msg3")
62 | n=n+1
63 | end)
64 |
65 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- hop to 4 o'clock
66 | assert(not ok)
67 | assert(strmatch(msg,"test error 3"), msg)
68 | assert(n==3)
69 |
70 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
71 | assert(msg=="msg4")
72 | n=n+1
73 | end)
74 |
75 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- again! it should still get the next event off of the queue.
76 | assert(not ok)
77 | assert(strmatch(msg,"test error 4"), msg)
78 | assert(n==4)
79 |
80 |
81 |
82 |
83 |
84 |
85 | -- Now we jump a loooong time into the future and make room for an immediate burst
86 | -- Errors should happen immediately on :Send now!
87 |
88 | WoWAPI_FireUpdate(100)
89 |
90 | n=0
91 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
92 | n=n+1
93 | assert(msg=="msg"..n, msg)
94 | end)
95 |
96 | n2=0
97 | local function callbackFn(arg)
98 | n2=n2+1
99 | assert(n2==n)
100 | error("test error "..n2)
101 | end
102 | for i=1,50 do -- 50 * ~50 = ~2500 bytes, max burst is 4000
103 | local ok,msg = pcall(ChatThrottleLib.SendAddonMessage, ChatThrottleLib,
104 | "NORMAL", "MyPrefix", "msg"..i, "SAY", nil, nil, callbackFn)
105 | assert(not ok)
106 | assert(strmatch(msg, "test error "..n2), msg)
107 | assert(n==i, n)
108 | assert(n2==i, n2)
109 | end
110 | assert(n==50 and n2==50)
111 |
112 | WoWAPI_FireUpdate(101) -- shouldn't cause anything untowards to happen
113 |
114 | assert(n==50 and n2==50)
115 |
116 | frame:UnregisterEvent("CHAT_MSG_ADDON")
117 | end
118 |
119 |
120 |
121 | ------------------------------------------------------------------------------
122 | print ("OK")
123 |
--------------------------------------------------------------------------------
/tests/AceConfigRegisty-3.0-errors.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | local MAJOR="AceConfigRegistry-3.0"
5 | dofile("../AceConfig-3.0/"..MAJOR.."/"..MAJOR..".lua")
6 |
7 | local creg = assert(LibStub(MAJOR))
8 |
9 | local errpattern = "^"..string.gsub(MAJOR,"-","%%-")..":ValidateOptionsTable"
10 |
11 | ---------------- the option table!!
12 |
13 | local opts = {
14 | type = "group",
15 | get = function(info) return true end,
16 | set = function(info,v) end,
17 | validate = function() return end,
18 |
19 | args = {
20 | input = {
21 | type="input",
22 | name="Input",
23 | },
24 | toggle = {
25 | type="toggle",
26 | name="Toggle",
27 | },
28 | grp = {
29 | type="group",
30 | name="Grp",
31 | args = {
32 | toggle = {
33 | type="toggle",
34 | name="Toggle",
35 | }
36 | }
37 | },
38 | select = {
39 | type="select",
40 | name="Select",
41 | desc="Styled!",
42 | style="dropdown",
43 | values={},
44 | }
45 | },
46 |
47 | plugins = { -- test plugins
48 | plugin1 = {
49 | plugcmd = {
50 | name="PluggedCmd",
51 | type="toggle",
52 | },
53 | plugcmd2 = {
54 | name="PluggedCmd2",
55 | type="toggle",
56 | }
57 | },
58 | }
59 | }
60 |
61 | creg:RegisterOptionsTable("testapp", opts)
62 |
63 | assert(creg:GetOptionsTable("testapp","cmd","foo-1") == opts)
64 |
65 | -- This should not error
66 | creg:ValidateOptionsTable(opts,"mytable")
67 |
68 | -----------------------------------------------------------------------
69 | -- Smack various things to pieces and make sure we get a validation error
70 | -- Make sure that errors are indicated on the right callstack offset!
71 |
72 | local function test(pattern)
73 | local ok,msg=pcall(creg.ValidateOptionsTable, creg, opts,"mytable")
74 | assert(not ok, "Wtf, this didnt error?")
75 | assert(string.match(msg, errpattern), "<"..msg.."> did not match <"..errpattern..">") -- error should point at the pcall == no location info
76 | assert(string.match(msg,pattern), "<"..msg.."> did not match <"..pattern..">")
77 | end
78 |
79 | opts.type=nil
80 | test("mytable.type")
81 | opts.type="group"
82 |
83 | opts.plugins.plugin1["bad\tkey"]=true
84 | test("mytable.plugins.plugin1.*contained control characters")
85 | opts.plugins.plugin1["bad\tkey"]=nil
86 |
87 | opts.plugins.mybad = "hi"
88 | test("mytable.plugins.mybad.*expected a table")
89 | opts.plugins.mybad = nil
90 |
91 | opts.plugins.plugin1.plugcmd.type="barf"
92 | test("unknown type")
93 | opts.plugins.plugin1.plugcmd.type="toggle"
94 |
95 | opts.args.select.style="hi2u"
96 | test("select.style.*expect string value 'hi2u'")
97 | opts.args.select.style="radio"
98 | assert(pcall(creg.ValidateOptionsTable, creg, opts,"mytable"))
99 | opts.args.select.style=nil
100 | assert(pcall(creg.ValidateOptionsTable, creg, opts,"mytable"))
101 |
102 | opts.args.select.values=nil
103 | test("select.values.*expected a methodname, funcref or table")
104 | opts.args.select.values={}
105 |
106 |
107 | -----------------------------------------------------------------------
108 | -- Make sure we get correct error message levels via other apis also
109 |
110 | opts.hateme=true
111 | local pattern="testapp.hateme.*unknown param"
112 |
113 | local ok,msg=pcall(creg.GetOptionsTable,creg,"testapp","dropdown","foo-1")
114 | assert(not ok)
115 | assert(string.match(msg, errpattern), "<"..msg.."> did not match <"..errpattern..">") -- error should point at the pcall == no location info
116 | assert(string.match(msg,pattern), "<"..msg.."> did not match <"..pattern..">")
117 |
118 | local ok,msg=pcall(creg:GetOptionsTable("testapp"),"dropdown","foo-1")
119 | assert(not ok)
120 | assert(string.match(msg, errpattern), "<"..msg.."> did not match <"..errpattern..">") -- error should point at the pcall == no location info
121 | assert(string.match(msg,pattern), "<"..msg.."> did not match <"..pattern..">")
122 |
123 |
124 |
125 |
126 |
127 | -----------------------------------------------------------------------
128 | print "OK"
129 |
--------------------------------------------------------------------------------
/tests/ChatThrottleLib-upgrade-20-current.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 |
3 |
4 | local ORIG_SendChatMessage = _G.SendChatMessage
5 |
6 |
7 | ------------------------------------------------------------------------
8 | -- Pull in v20
9 |
10 | dofile("ChatThrottleLibs/ChatThrottleLib-v20.lua")
11 |
12 | local AfterV20_SendChatMessage = _G.SendChatMessage
13 | assert(AfterV20_SendChatMessage ~= ORIG_SendChatMessage) -- we should have securehooked it
14 |
15 |
16 | ------------------------------------------------------------------------
17 | -- Queue up some messages - they should live through the upgrades below!
18 |
19 | local frame=CreateFrame("Frame")
20 | frame:RegisterEvent("CHAT_MSG_ADDON")
21 | frame:SetScript("OnEvent", function() error("Shouldn't see this yet!") end)
22 |
23 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg1", "SAY")
24 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg2", "SAY")
25 |
26 | WoWAPI_FireUpdate(0) -- 0 o'clock - no bandwidth available yet
27 |
28 |
29 |
30 |
31 |
32 | ------------------------------------------------------------------------
33 | -- Now pull in v21+
34 |
35 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
36 |
37 | local AfterV21_SendChatMessage = _G.SendChatMessage
38 | assert(AfterV21_SendChatMessage == AfterV20_SendChatMessage) -- should not have been touched
39 |
40 |
41 |
42 |
43 | ------------------------------------------------------------------------
44 | -- Now start pumping OnUpdates and see if our messages survived!
45 |
46 | local n=0
47 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
48 | assert(msg=="msg1")
49 | n=n+1
50 | end)
51 |
52 | WoWAPI_FireUpdate(1) -- 1 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
53 | assert(n==1)
54 |
55 | WoWAPI_FireUpdate(1) -- 1 o'clock again
56 | assert(n==1) -- WE SHOULD NOT SEE ANOTHER MESSAGE YET
57 |
58 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
59 | assert(msg=="msg2")
60 | n=n+1
61 | end)
62 |
63 | WoWAPI_FireUpdate(2) -- 2 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
64 | assert(n==2)
65 |
66 |
67 | ------------------------------------------------------------------------
68 | -- Now queue 2 messages up and hop 2 seconds into the future. (And pulse there twice)
69 | -- (Basic functionality test)
70 |
71 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg3", "WHISPER", "target1", nil,
72 | function() error("test error 3") end
73 | )
74 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg4", "WHISPER", "target2", nil,
75 | function() error("test error 4") end
76 | )
77 |
78 |
79 |
80 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
81 | assert(msg=="msg3")
82 | n=n+1
83 | end)
84 |
85 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- hop to 4 o'clock
86 | assert(not ok)
87 | assert(strmatch(msg,"test error 3"), msg)
88 | assert(n==3)
89 |
90 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
91 | assert(msg=="msg4")
92 | n=n+1
93 | end)
94 |
95 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- again! it should still get the next event off of the queue.
96 | assert(not ok)
97 | assert(strmatch(msg,"test error 4"), msg)
98 | assert(n==4)
99 |
100 |
101 |
102 |
103 |
104 | ------------------------------------------------------------------------
105 | -- Now we jump a loooong time into the future and make room for an immediate burst
106 | -- (Basic functionality test)
107 |
108 | WoWAPI_FireUpdate(100)
109 |
110 | n=0
111 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
112 | n=n+1
113 | assert(msg=="msg"..n, msg)
114 | end)
115 |
116 | for i=1,50 do -- 50 * ~50 = ~2500 bytes, max burst is 4000
117 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg"..i, "SAY")
118 | assert(n==i, n)
119 | end
120 | assert(n==50)
121 |
122 | WoWAPI_FireUpdate(101) -- shouldn't cause anything untowards to happen
123 |
124 | assert(n==50)
125 |
126 |
127 |
128 |
129 | ------------------------------------------------------------------------------
130 | print ("OK")
--------------------------------------------------------------------------------
/tests/AceLocale-3.0-test2.lua:
--------------------------------------------------------------------------------
1 |
2 | dofile("wow_api.lua")
3 |
4 |
5 | dofile("LibStub.lua")
6 | dofile("../AceLocale-3.0/AceLocale-3.0.lua")
7 |
8 | local AL = assert(LibStub("AceLocale-3.0"))
9 |
10 | ------------------------------------------
11 | -- Create enUS locale
12 |
13 | local L = assert(AL:NewLocale("Loc1", "enUS", true))
14 | L["foo1"] = true
15 |
16 | local L = assert(AL:NewLocale("Loc1", "enUS", true)) -- should be ok to add more!
17 | L["foo1"] = "this should not overwrite foo1 since this a default locale"
18 | L["foo2"] = "manual foo2"
19 | L["foo2"] = "this should not overwrite foo2 since this a default locale"
20 |
21 |
22 | local x="untouched"
23 | ok, msg = pcall(function() x = L["i can't read from write proxies"] end)
24 | assert(not ok, "got: "..tostring(ok))
25 | assert(x=="untouched", "got: "..tostring(x))
26 | assert(strfind(msg, "assertion failed"), "got: "..tostring(msg))
27 |
28 |
29 |
30 |
31 | -------------------------------------------
32 | -- Test enUS locale
33 |
34 | local L = assert(AL:GetLocale("Loc1"))
35 | assert(L["foo1"] == "foo1")
36 | assert(L["foo2"] == "manual foo2")
37 |
38 | -- test warning system for nonexistant strings
39 | local errormsg
40 | function geterrorhandler() return function(msg) errormsg=msg end end
41 |
42 | assert(L["this doesn't exist"]=="this doesn't exist")
43 | assert(errormsg=="AceLocale-3.0: Loc1: Missing entry for 'this doesn't exist'", "got: "..errormsg)
44 |
45 | -- we shouldnt get warnings for the same string twice
46 | errormsg="no error"
47 |
48 | assert(L["this doesn't exist"]=="this doesn't exist")
49 | assert(errormsg=="no error")
50 |
51 |
52 | -- (don't) create deDE locale
53 | local L = AL:NewLocale("Loc1", "deDE")
54 | assert(not L)
55 |
56 |
57 |
58 |
59 | -------------------------------------------
60 | -- Get locale for nonexisting app
61 |
62 | -- silent
63 | local L = AL:GetLocale("Loc2", true)
64 | assert(not L)
65 |
66 | -- nonsilent - should error
67 | local ok, msg = pcall(function() return AL:GetLocale("Loc2") end)
68 | assert(not ok, "got: "..tostring(ok))
69 | assert(msg=="Usage: GetLocale(application[, silent]): 'application' - No locales registered for 'Loc2'", "got: "..tostring(msg))
70 |
71 |
72 |
73 |
74 |
75 |
76 | ---------------------------------------------------------------
77 | ---------------------------------------------------------------
78 | ---------------------------------------------------------------
79 | --
80 | -- Hi2u, we're a german client now!
81 | --
82 |
83 |
84 | function GetLocale() return "deDE" end
85 |
86 | LibStub = nil
87 | dofile("LibStub.lua")
88 | dofile("../AceLocale-3.0/AceLocale-3.0.lua")
89 |
90 | local AL = assert(LibStub("AceLocale-3.0"))
91 |
92 |
93 |
94 | assert( not AL:NewLocale("Loc1", "frFR") ) -- no, we're still not french
95 |
96 |
97 | ---------------------------------------------------------------
98 | -- Register deDE
99 |
100 | local L = assert(AL:NewLocale("Loc1", "deDE"))
101 | L["yes"]="jawohl"
102 | L["no"]="nein"
103 |
104 |
105 | ---------------------------------------------------------------
106 | -- Register enUS (default)
107 |
108 | local L = assert(AL:NewLocale("Loc1", "enUS", true))
109 | L["yes"]=true
110 | L["no"]="no"
111 | L["untranslated"]="untranslated"
112 |
113 | ---------------------------------------------------------------
114 | -- Test deDE
115 |
116 | local L = assert(AL:GetLocale("Loc1"))
117 | assert(L["yes"]=="jawohl")
118 | assert(L["no"]=="nein")
119 | assert(L["untranslated"]=="untranslated")
120 |
121 |
122 |
123 |
124 | ---------------------------------------------------------------
125 | ---------------------------------------------------------------
126 | ---------------------------------------------------------------
127 | --
128 | -- Test overriding with GAME_LOCALE
129 | --
130 |
131 | GAME_LOCALE = "frFR"
132 |
133 | assert(not AL:NewLocale("Loc1", "deDE")) -- shouldn't be krauts anymore now
134 |
135 | local L = assert(AL:NewLocale("Loc1", "frFR")) -- we're frog eaters!
136 | L["yes"] = "oui"
137 |
138 | local L = assert(AL:GetLocale("Loc1"))
139 | assert(L["yes"] == "oui") -- should have been overwritten
140 | assert(L["no"] == "nein") -- should be left from kraut days
141 |
142 |
143 | ---------------------------------------------------------------
144 |
145 | print "OK"
146 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | BlizOptionsGroup Container
3 | Simple container widget for the integration of AceGUI into the Blizzard Interface Options
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "BlizOptionsGroup", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 |
19 | local function OnShow(frame)
20 | frame.obj:Fire("OnShow")
21 | end
22 |
23 | local function OnHide(frame)
24 | frame.obj:Fire("OnHide")
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Support functions
29 | -------------------------------------------------------------------------------]]
30 |
31 | local function okay(frame)
32 | frame.obj:Fire("okay")
33 | end
34 |
35 | local function cancel(frame)
36 | frame.obj:Fire("cancel")
37 | end
38 |
39 | local function default(frame)
40 | frame.obj:Fire("default")
41 | end
42 |
43 | local function refresh(frame)
44 | frame.obj:Fire("refresh")
45 | end
46 |
47 | --[[-----------------------------------------------------------------------------
48 | Methods
49 | -------------------------------------------------------------------------------]]
50 |
51 | local methods = {
52 | ["OnAcquire"] = function(self)
53 | self:SetName()
54 | self:SetTitle()
55 | end,
56 |
57 | -- ["OnRelease"] = nil,
58 |
59 | ["OnWidthSet"] = function(self, width)
60 | local content = self.content
61 | local contentwidth = width - 63
62 | if contentwidth < 0 then
63 | contentwidth = 0
64 | end
65 | content:SetWidth(contentwidth)
66 | content.width = contentwidth
67 | end,
68 |
69 | ["OnHeightSet"] = function(self, height)
70 | local content = self.content
71 | local contentheight = height - 26
72 | if contentheight < 0 then
73 | contentheight = 0
74 | end
75 | content:SetHeight(contentheight)
76 | content.height = contentheight
77 | end,
78 |
79 | ["SetName"] = function(self, name, parent)
80 | self.frame.name = name
81 | self.frame.parent = parent
82 | end,
83 |
84 | ["SetTitle"] = function(self, title)
85 | local content = self.content
86 | content:ClearAllPoints()
87 | if not title or title == "" then
88 | content:SetPoint("TOPLEFT", 10, -10)
89 | self.label:SetText("")
90 | else
91 | content:SetPoint("TOPLEFT", 10, -40)
92 | self.label:SetText(title)
93 | end
94 | content:SetPoint("BOTTOMRIGHT", -10, 10)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local function Constructor()
102 | local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
103 | frame:Hide()
104 |
105 | -- support functions for the Blizzard Interface Options
106 | frame.okay = okay
107 | frame.cancel = cancel
108 | frame.default = default
109 | frame.refresh = refresh
110 |
111 | -- 10.0 support function aliases (cancel has been removed)
112 | frame.OnCommit = okay
113 | frame.OnDefault = default
114 | frame.OnRefresh = refresh
115 |
116 | frame:SetScript("OnHide", OnHide)
117 | frame:SetScript("OnShow", OnShow)
118 |
119 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
120 | label:SetPoint("TOPLEFT", 10, -15)
121 | label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
122 | label:SetJustifyH("LEFT")
123 | label:SetJustifyV("TOP")
124 |
125 | --Container Support
126 | local content = CreateFrame("Frame", nil, frame)
127 | content:SetPoint("TOPLEFT", 10, -10)
128 | content:SetPoint("BOTTOMRIGHT", -10, 10)
129 |
130 | local widget = {
131 | label = label,
132 | frame = frame,
133 | content = content,
134 | type = Type
135 | }
136 | for method, func in pairs(methods) do
137 | widget[method] = func
138 | end
139 |
140 | return AceGUI:RegisterAsContainer(widget)
141 | end
142 |
143 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
144 |
--------------------------------------------------------------------------------
/tests/AceConsole-3.0-GetArgs.lua:
--------------------------------------------------------------------------------
1 |
2 | local MAJOR="AceConsole-3.0"
3 |
4 | dofile("wow_api.lua")
5 |
6 | dofile("LibStub.lua")
7 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
8 |
9 |
10 | local AC = assert(LibStub(MAJOR))
11 |
12 |
13 |
14 |
15 | ----------------------------------------------------------
16 | -- Simple tests
17 | -- (no need to explicitly test startpos; if multi-arg tests work, it works)
18 |
19 | local a1,a2 = AC:GetArgs("") -- no arg
20 | assert(a1==nil and a2==1e9)
21 |
22 | local a1,a2 = AC:GetArgs(" ") -- still no arg
23 | assert(a1==nil and a2==1e9)
24 |
25 | local a1,a2 = AC:GetArgs("a1") -- simple
26 | assert(a1=="a1" and a2==1e9)
27 |
28 | local a1 = AC:GetArgs("a1", 0) -- fetch 0 args
29 | assert(a1==1)
30 |
31 | local a1 = AC:GetArgs(" a1", 0) -- fetch 0 args, leading space
32 | assert(a1==3)
33 |
34 | local a1,a2 = AC:GetArgs("a1 a2") -- args remaining, check nextpos
35 | assert(a1=="a1" and a2==4)
36 |
37 | local a1,a2 = AC:GetArgs("a1 a2") -- args remaining, check nextpos
38 | assert(a1=="a1" and a2==6, dump(a1,a2))
39 |
40 | local a1,a2,a3 = AC:GetArgs("a1 a2", 2) -- 2 args
41 | assert(a1=="a1" and a2=="a2" and a3==1e9)
42 |
43 | local a1,a2,a3 = AC:GetArgs(" a1 a2 ", 2) -- surplous space
44 | assert(a1=="a1" and a2=="a2" and a3==1e9, dump(a1,a2,a3))
45 |
46 | local a1,a2,a3 = AC:GetArgs(" a1 a2 ", 2) -- one more space at end
47 | assert(a1=="a1" and a2=="a2" and a3==1e9, dump(a1,a2,a3))
48 |
49 |
50 | local a1,a2,a3 = AC:GetArgs(" a1 ", 2) -- missing arg2
51 | assert(a1=="a1" and a2==nil and a3==1e9, dump(a1,a2,a3))
52 |
53 |
54 |
55 | ----------------------------------------------------------
56 | -- Test quoting
57 |
58 | local a1,a2 = AC:GetArgs([["a1"]]) -- simple quote
59 | assert(a1=="a1" and a2==1e9, dump(a1,a2))
60 |
61 | local a1,a2 = AC:GetArgs([["a 1"]]) -- quote with space in it
62 | assert(a1=="a 1" and a2==1e9, dump(a1,a2))
63 |
64 | local a1,a2 = AC:GetArgs([[" a 1 "]]) -- quote with space at beginning and end
65 | assert(a1==" a 1 " and a2==1e9, dump(a1,a2))
66 |
67 | local a1,a2 = AC:GetArgs([['a 1']]) -- single quote
68 | assert(a1=="a 1" and a2==1e9, dump(a1,a2))
69 |
70 | local a1,a2,a3 = AC:GetArgs([["a 1" "a 2"]], 2) -- 2 args
71 | assert(a1=="a 1" and a2=="a 2" and a3==1e9, dump(a1,a2,a3))
72 |
73 | local a1,a2,a3 = AC:GetArgs([["a 1" 'a 2']], 2) -- mixed quoting
74 | assert(a1=="a 1" and a2=="a 2" and a3==1e9, dump(a1,a2,a3))
75 |
76 | local a1,a2,a3 = AC:GetArgs([[ "a 1" 'a 2' ]], 2) -- surplous spacing between quotes
77 | assert(a1=="a 1" and a2=="a 2" and a3==1e9, dump(a1,a2,a3))
78 |
79 | local a1,a2,a3 = AC:GetArgs([["foo'bar" 'foo"bar']], 2) -- don't break on nonmatching quote
80 | assert(a1=="foo'bar" and a2=='foo"bar' and a3==1e9, dump(a1,a2,a3))
81 |
82 | local a1,a2 = AC:GetArgs([[ "unfinished quote]], 1) -- missing " at end
83 | assert(a1=="unfinished quote" and a2==1e9, dump(a1,a2))
84 |
85 |
86 | ------------------------------------------------------------
87 | -- Hyperlinks and combos
88 |
89 | local a1,a2,a3,a4 = AC:GetArgs("simple |Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r", 3)
90 | assert(a1=="simple" and a2=="|Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r" and a3==nil and a4==1e9, dump(a1,a2,a3,a4))
91 |
92 | local a1,a2,a3,a4 = AC:GetArgs("simple '|Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r'", 3)
93 | assert(a1=="simple" and a2=="|Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r" and a3==nil and a4==1e9, dump(a1,a2,a3,a4))
94 |
95 | local a1,a2,a3,a4 = AC:GetArgs("simple \"|Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r\" 'bar'", 3)
96 | assert(a1=="simple" and a2=="|Cff112233|Hitem:0:0:0:0|hand here's a text with \"s and stuff|h|r" and a3=="bar" and a4==1e9, dump(a1,a2,a3,a4))
97 |
98 | local a1,a2,a3,a4 = AC:GetArgs("simple |H|ha 1|h|H|ha 1|h", 3)
99 | assert(a1=="simple" and a2=="|H|ha 1|h|H|ha 1|h" and a3==nil and a4==1e9, dump(a1,a2,a3,a4))
100 |
101 | local a1,a2,a3,a4 = AC:GetArgs("simple ||H|ha 1|h|H|ha 1|h", 3) -- note double ||
102 | assert(a1=="simple" and a2=="||H|ha" and a3=="1|h|H|ha 1|h" and a4==1e9, dump(a1,a2,a3,a4))
103 |
104 | local a1,a2,a3,a4 = AC:GetArgs("simple |||H|ha 1|h|H|ha 1|h", 3) -- note double || followed by |H
105 | assert(a1=="simple" and a2=="|||H|ha 1|h|H|ha 1|h" and a3==nil and a4==1e9, dump(a1,a2,a3,a4))
106 |
107 |
108 | ------------------------------------------------------------
109 | print "OK"
110 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Icon Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Icon", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs, print = select, pairs, print
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Scripts
16 | -------------------------------------------------------------------------------]]
17 | local function Control_OnEnter(frame)
18 | frame.obj:Fire("OnEnter")
19 | end
20 |
21 | local function Control_OnLeave(frame)
22 | frame.obj:Fire("OnLeave")
23 | end
24 |
25 | local function Button_OnClick(frame, button)
26 | frame.obj:Fire("OnClick", button)
27 | AceGUI:ClearFocus()
28 | end
29 |
30 | --[[-----------------------------------------------------------------------------
31 | Methods
32 | -------------------------------------------------------------------------------]]
33 | local methods = {
34 | ["OnAcquire"] = function(self)
35 | self:SetHeight(110)
36 | self:SetWidth(110)
37 | self:SetLabel()
38 | self:SetImage(nil)
39 | self:SetImageSize(64, 64)
40 | self:SetDisabled(false)
41 | end,
42 |
43 | -- ["OnRelease"] = nil,
44 |
45 | ["SetLabel"] = function(self, text)
46 | if text and text ~= "" then
47 | self.label:Show()
48 | self.label:SetText(text)
49 | self:SetHeight(self.image:GetHeight() + 25)
50 | else
51 | self.label:Hide()
52 | self:SetHeight(self.image:GetHeight() + 10)
53 | end
54 | end,
55 |
56 | ["SetImage"] = function(self, path, ...)
57 | local image = self.image
58 | image:SetTexture(path)
59 |
60 | if image:GetTexture() then
61 | local n = select("#", ...)
62 | if n == 4 or n == 8 then
63 | image:SetTexCoord(...)
64 | else
65 | image:SetTexCoord(0, 1, 0, 1)
66 | end
67 | end
68 | end,
69 |
70 | ["SetImageSize"] = function(self, width, height)
71 | self.image:SetWidth(width)
72 | self.image:SetHeight(height)
73 | --self.frame:SetWidth(width + 30)
74 | if self.label:IsShown() then
75 | self:SetHeight(height + 25)
76 | else
77 | self:SetHeight(height + 10)
78 | end
79 | end,
80 |
81 | ["SetDisabled"] = function(self, disabled)
82 | self.disabled = disabled
83 | if disabled then
84 | self.frame:Disable()
85 | self.label:SetTextColor(0.5, 0.5, 0.5)
86 | self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
87 | else
88 | self.frame:Enable()
89 | self.label:SetTextColor(1, 1, 1)
90 | self.image:SetVertexColor(1, 1, 1, 1)
91 | end
92 | end
93 | }
94 |
95 | --[[-----------------------------------------------------------------------------
96 | Constructor
97 | -------------------------------------------------------------------------------]]
98 | local function Constructor()
99 | local frame = CreateFrame("Button", nil, UIParent)
100 | frame:Hide()
101 |
102 | frame:EnableMouse(true)
103 | frame:SetScript("OnEnter", Control_OnEnter)
104 | frame:SetScript("OnLeave", Control_OnLeave)
105 | frame:SetScript("OnClick", Button_OnClick)
106 |
107 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
108 | label:SetPoint("BOTTOMLEFT")
109 | label:SetPoint("BOTTOMRIGHT")
110 | label:SetJustifyH("CENTER")
111 | label:SetJustifyV("TOP")
112 | label:SetHeight(18)
113 |
114 | local image = frame:CreateTexture(nil, "BACKGROUND")
115 | image:SetWidth(64)
116 | image:SetHeight(64)
117 | image:SetPoint("TOP", 0, -5)
118 |
119 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
120 | highlight:SetAllPoints(image)
121 | highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight
122 | highlight:SetTexCoord(0, 1, 0.23, 0.77)
123 | highlight:SetBlendMode("ADD")
124 |
125 | local widget = {
126 | label = label,
127 | image = image,
128 | frame = frame,
129 | type = Type
130 | }
131 | for method, func in pairs(methods) do
132 | widget[method] = func
133 | end
134 |
135 | widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
136 |
137 | return AceGUI:RegisterAsWidget(widget)
138 | end
139 |
140 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
141 |
--------------------------------------------------------------------------------
/tests/AceTimer-3.0-test2.lua:
--------------------------------------------------------------------------------
1 |
2 | -- AceTimer test suite 2: Errors
3 |
4 |
5 | dofile("wow_api.lua")
6 | dofile("LibStub.lua")
7 |
8 | local MAJOR = "AceTimer-3.0"
9 |
10 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
11 |
12 | local AceTimer,minor = LibStub:GetLibrary(MAJOR)
13 |
14 | -- NOTE, the below pcalls should NOT contain error position information.
15 | -- The reason is that if the error level is correctly set, it will point to _inside_ the pcall(), which does not have a position
16 |
17 |
18 | -------------------------------------------------------------------
19 | -- Test ScheduleTimer errorchecking of method
20 |
21 | obj = {}
22 |
23 | ok,msg = pcall(AceTimer.ScheduleTimer, obj, "method", 4, "arg") -- This should fail - method not defined
24 | assert(not ok)
25 | assert(msg == MAJOR..": ScheduleTimer(\"methodName\", delay, arg): 'methodName' - method not found on target object.", msg)
26 |
27 |
28 | obj.method = "hi, i'm NOT a function, i'm something else"
29 |
30 | ok,msg = pcall(AceTimer.ScheduleTimer, obj, "method", 4, "arg") -- This should fail - obj["method"] is not a function
31 | assert(not ok)
32 | assert(msg == MAJOR..": ScheduleTimer(\"methodName\", delay, arg): 'methodName' - method not found on target object.", msg)
33 |
34 |
35 | ok,msg = pcall(AceTimer.ScheduleTimer, obj, nil, 4, "arg") -- This should fail (method is nil)
36 | assert(not ok)
37 | assert(msg == MAJOR..": ScheduleTimer(callback, delay, arg): 'callback' - function or method name expected.", msg)
38 |
39 |
40 | ok,msg = pcall(AceTimer.ScheduleTimer, obj, {}, 4, "arg") -- This should fail (method is table)
41 | assert(not ok)
42 | assert(msg == MAJOR..": ScheduleTimer(callback, delay, arg): 'callback' - function or method name expected.", msg)
43 |
44 |
45 | -- (Note: ScheduleRepeatingTimer here just to check naming)
46 | ok,msg = pcall(AceTimer.ScheduleRepeatingTimer, obj, 123, 4, "arg") -- This should fail too (method is integer)
47 | assert(not ok)
48 | assert(msg == MAJOR..": ScheduleRepeatingTimer(callback, delay, arg): 'callback' - function or method name expected.", msg)
49 |
50 |
51 |
52 | -------------------------------------------------------------------
53 | -- Check AceTimer:CancelAllTimers() -- not allowed
54 |
55 | ok,msg = pcall(AceTimer.CancelAllTimers, AceTimer)
56 | assert(not ok)
57 | assert(msg == MAJOR..": CancelAllTimers(): supply a meaningful 'self'", dump(msg))
58 |
59 |
60 | -------------------------------------------------------------------
61 | -- Scheduling a timer on a member function that later becomes a nonfunction
62 |
63 | cnt=0
64 | obj.method = function() cnt=cnt+1 end
65 |
66 | AceTimer.ScheduleRepeatingTimer(obj, "method", 1, "arg")
67 |
68 | WoWAPI_FireUpdate(2) -- Border case: at this exact bucket, we should be able to convince the timer to fire twice even though it only gets a single onupdate
69 | assert(cnt==2, cnt) -- This should have worked nicely
70 |
71 | errors=0
72 | function geterrorhandler()
73 | return function(msg)
74 | errors=errors+1
75 | assert(strmatch(msg, "a string value"))
76 | end
77 | end
78 |
79 | obj.method = "this should cause errors"
80 | WoWAPI_FireUpdate(4)
81 |
82 | assert(errors==2) -- timer should have run twice
83 |
84 |
85 | -----------------------------------------------------------------------
86 | -- :CancelTimer() on something that's already cancelled / never existed
87 |
88 | local handle = AceTimer.ScheduleTimer(obj, function() assert("this shouldnt run") end, 1)
89 |
90 | AceTimer.CancelTimer(obj, handle) -- Should work
91 |
92 |
93 | errors=0
94 | function geterrorhandler()
95 | return function(msg)
96 | errors=errors+1
97 | assert(strmatch(msg, "already cancelled"))
98 | end
99 | end
100 |
101 | AceTimer.CancelTimer(obj, handle) -- Should error -- already cancelled
102 | assert(errors==1)
103 |
104 |
105 | WoWAPI_FireUpdate(6) -- Let the timer disappear from the buckets
106 |
107 |
108 | errors=0
109 | function geterrorhandler()
110 | return function(msg)
111 | errors=errors+1
112 | assert(strmatch(msg, "no such timer"))
113 | end
114 | end
115 |
116 | AceTimer.CancelTimer(obj, handle) -- Should error -- doesnt exist at all
117 | assert(errors==1)
118 |
119 |
120 | function geterrorhandler()
121 | return function(msg)
122 | error("This shouldn't have errored! -- "..msg)
123 | end
124 | end
125 | AceTimer.CancelTimer(obj, handle, true) -- silent: shouldn't error
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | -----------------------------------------------------------------------
135 |
136 | print "OK"
137 |
--------------------------------------------------------------------------------
/tests/ChatThrottleLib-upgrade-14-20-current.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 |
3 |
4 | local ORIG_SendChatMessage = _G.SendChatMessage
5 |
6 | ------------------------------------------------------------------------
7 | -- Pull in v14
8 | dofile("ChatThrottleLibs/ChatThrottleLib-v14.lua")
9 |
10 |
11 | local AfterV14_SendChatMessage = _G.SendChatMessage
12 | assert(AfterV14_SendChatMessage ~= ORIG_SendChatMessage)
13 |
14 |
15 | ------------------------------------------------------------------------
16 | -- Queue up some messages - they should live through the upgrades below!
17 |
18 | local frame=CreateFrame("Frame")
19 | frame:RegisterEvent("CHAT_MSG_ADDON")
20 | frame:SetScript("OnEvent", function() error("Shouldn't see this yet!") end)
21 |
22 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg1", "SAY")
23 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg2", "SAY")
24 |
25 | WoWAPI_FireUpdate(0) -- 0 o'clock - no bandwidth available yet
26 |
27 |
28 |
29 | ------------------------------------------------------------------------
30 | -- Now pull in v20, should be straightforward, will still use the old hook
31 |
32 | dofile("ChatThrottleLibs/ChatThrottleLib-v20.lua")
33 |
34 | local AfterV20_SendChatMessage = _G.SendChatMessage
35 | assert(AfterV20_SendChatMessage == AfterV14_SendChatMessage)
36 |
37 |
38 |
39 |
40 | ------------------------------------------------------------------------
41 | -- Now pull in v21+, which will complain about v14 being ANCIENT and attempt to restore the original handlers
42 |
43 | local origprint = print
44 | local nAncient = 0
45 | _G.print = function(...)
46 | if strmatch(..., "ANCIENT") then
47 | nAncient = nAncient + 1
48 | else
49 | return origprint(...)
50 | end
51 | end
52 |
53 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
54 |
55 | assert(nAncient==1) -- did it complain?
56 |
57 | _G.print = origprint
58 |
59 | local AfterV21_SendChatMessage = _G.SendChatMessage
60 | assert(AfterV21_SendChatMessage ~= AfterV14_SendChatMessage)
61 |
62 |
63 |
64 |
65 | ------------------------------------------------------------------------
66 | -- Now start pumping OnUpdates and see if our messages survived!
67 |
68 | local n=0
69 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
70 | assert(msg=="msg1")
71 | n=n+1
72 | end)
73 |
74 | WoWAPI_FireUpdate(1) -- 1 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
75 | assert(n==1)
76 |
77 | WoWAPI_FireUpdate(1) -- 1 o'clock again
78 | assert(n==1) -- WE SHOULD NOT SEE ANOTHER MESSAGE YET
79 |
80 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
81 | assert(msg=="msg2")
82 | n=n+1
83 | end)
84 |
85 | WoWAPI_FireUpdate(2) -- 2 o'clock. CTL starts up in "hard clamping mode", so should only allow 80 CPS for the first few seconds
86 | assert(n==2)
87 |
88 |
89 | ------------------------------------------------------------------------
90 | -- Now queue 2 messages up and hop 2 seconds into the future. (And pulse there twice)
91 | -- (Basic functionality test)
92 |
93 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg3", "WHISPER", "target1", nil,
94 | function() error("test error 3") end
95 | )
96 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg4", "WHISPER", "target2", nil,
97 | function() error("test error 4") end
98 | )
99 |
100 |
101 |
102 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
103 | assert(msg=="msg3")
104 | n=n+1
105 | end)
106 |
107 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- hop to 4 o'clock
108 | assert(not ok)
109 | assert(strmatch(msg,"test error 3"), msg)
110 | assert(n==3)
111 |
112 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
113 | assert(msg=="msg4")
114 | n=n+1
115 | end)
116 |
117 | local ok,msg = pcall(WoWAPI_FireUpdate,4) -- again! it should still get the next event off of the queue.
118 | assert(not ok)
119 | assert(strmatch(msg,"test error 4"), msg)
120 | assert(n==4)
121 |
122 |
123 |
124 |
125 |
126 | ------------------------------------------------------------------------
127 | -- Now we jump a loooong time into the future and make room for an immediate burst
128 | -- (Basic functionality test)
129 |
130 | WoWAPI_FireUpdate(100)
131 |
132 | n=0
133 | frame:SetScript("OnEvent", function(self, event, prefix, msg)
134 | n=n+1
135 | assert(msg=="msg"..n, msg)
136 | end)
137 |
138 | for i=1,50 do -- 50 * ~50 = ~2500 bytes, max burst is 4000
139 | ChatThrottleLib:SendAddonMessage("NORMAL", "MyPrefix", "msg"..i, "SAY")
140 | assert(n==i, n)
141 | end
142 | assert(n==50)
143 |
144 | WoWAPI_FireUpdate(101) -- shouldn't cause anything untowards to happen
145 |
146 | assert(n==50)
147 |
148 |
149 |
150 |
151 | ------------------------------------------------------------------------------
152 | print ("OK")
153 |
--------------------------------------------------------------------------------
/AceEvent-3.0/AceEvent-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceEvent-3.0 provides event registration and secure dispatching.
2 | -- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
3 | -- CallbackHandler, and dispatches all game events or addon message to the registrees.
4 | --
5 | -- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceEvent itself.\\
8 | -- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceEvent.
10 | -- @class file
11 | -- @name AceEvent-3.0
12 | -- @release $Id$
13 | local CallbackHandler = LibStub("CallbackHandler-1.0")
14 |
15 | local MAJOR, MINOR = "AceEvent-3.0", 4
16 | local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
17 |
18 | if not AceEvent then return end
19 |
20 | -- Lua APIs
21 | local pairs = pairs
22 |
23 | AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
24 | AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
25 |
26 | -- APIs and registry for blizzard events, using CallbackHandler lib
27 | if not AceEvent.events then
28 | AceEvent.events = CallbackHandler:New(AceEvent,
29 | "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
30 | end
31 |
32 | function AceEvent.events:OnUsed(target, eventname)
33 | AceEvent.frame:RegisterEvent(eventname)
34 | end
35 |
36 | function AceEvent.events:OnUnused(target, eventname)
37 | AceEvent.frame:UnregisterEvent(eventname)
38 | end
39 |
40 |
41 | -- APIs and registry for IPC messages, using CallbackHandler lib
42 | if not AceEvent.messages then
43 | AceEvent.messages = CallbackHandler:New(AceEvent,
44 | "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
45 | )
46 | AceEvent.SendMessage = AceEvent.messages.Fire
47 | end
48 |
49 | --- embedding and embed handling
50 | local mixins = {
51 | "RegisterEvent", "UnregisterEvent",
52 | "RegisterMessage", "UnregisterMessage",
53 | "SendMessage",
54 | "UnregisterAllEvents", "UnregisterAllMessages",
55 | }
56 |
57 | --- Register for a Blizzard Event.
58 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
59 | -- Any arguments to the event will be passed on after that.
60 | -- @name AceEvent:RegisterEvent
61 | -- @class function
62 | -- @paramsig event[, callback [, arg]]
63 | -- @param event The event to register for
64 | -- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
65 | -- @param arg An optional argument to pass to the callback function
66 |
67 | --- Unregister an event.
68 | -- @name AceEvent:UnregisterEvent
69 | -- @class function
70 | -- @paramsig event
71 | -- @param event The event to unregister
72 |
73 | --- Register for a custom AceEvent-internal message.
74 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
75 | -- Any arguments to the event will be passed on after that.
76 | -- @name AceEvent:RegisterMessage
77 | -- @class function
78 | -- @paramsig message[, callback [, arg]]
79 | -- @param message The message to register for
80 | -- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
81 | -- @param arg An optional argument to pass to the callback function
82 |
83 | --- Unregister a message
84 | -- @name AceEvent:UnregisterMessage
85 | -- @class function
86 | -- @paramsig message
87 | -- @param message The message to unregister
88 |
89 | --- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
90 | -- @name AceEvent:SendMessage
91 | -- @class function
92 | -- @paramsig message, ...
93 | -- @param message The message to send
94 | -- @param ... Any arguments to the message
95 |
96 |
97 | -- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
98 | -- @param target target object to embed AceEvent in
99 | function AceEvent:Embed(target)
100 | for k, v in pairs(mixins) do
101 | target[v] = self[v]
102 | end
103 | self.embeds[target] = true
104 | return target
105 | end
106 |
107 | -- AceEvent:OnEmbedDisable( target )
108 | -- target (object) - target object that is being disabled
109 | --
110 | -- Unregister all events messages etc when the target disables.
111 | -- this method should be called by the target manually or by an addon framework
112 | function AceEvent:OnEmbedDisable(target)
113 | target:UnregisterAllEvents()
114 | target:UnregisterAllMessages()
115 | end
116 |
117 | -- Script to fire blizzard events into the event listeners
118 | local events = AceEvent.events
119 | AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
120 | events:Fire(event, ...)
121 | end)
122 |
123 | --- Finally: upgrade our old embeds
124 | for target, v in pairs(AceEvent.embeds) do
125 | AceEvent:Embed(target)
126 | end
127 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | DropdownGroup Container
3 | Container controlled by a dropdown on the top.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "DropdownGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local assert, pairs, type = assert, pairs, type
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 | local function SelectedGroup(self, event, value)
19 | local group = self.parentgroup
20 | local status = group.status or group.localstatus
21 | status.selected = value
22 | self.parentgroup:Fire("OnGroupSelected", value)
23 | end
24 |
25 | --[[-----------------------------------------------------------------------------
26 | Methods
27 | -------------------------------------------------------------------------------]]
28 | local methods = {
29 | ["OnAcquire"] = function(self)
30 | self.dropdown:SetText("")
31 | self:SetDropdownWidth(200)
32 | self:SetTitle("")
33 | end,
34 |
35 | ["OnRelease"] = function(self)
36 | self.dropdown.list = nil
37 | self.status = nil
38 | for k in pairs(self.localstatus) do
39 | self.localstatus[k] = nil
40 | end
41 | end,
42 |
43 | ["SetTitle"] = function(self, title)
44 | self.titletext:SetText(title)
45 | self.dropdown.frame:ClearAllPoints()
46 | if title and title ~= "" then
47 | self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
48 | else
49 | self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
50 | end
51 | end,
52 |
53 | ["SetGroupList"] = function(self,list,order)
54 | self.dropdown:SetList(list,order)
55 | end,
56 |
57 | ["SetStatusTable"] = function(self, status)
58 | assert(type(status) == "table")
59 | self.status = status
60 | end,
61 |
62 | ["SetGroup"] = function(self,group)
63 | self.dropdown:SetValue(group)
64 | local status = self.status or self.localstatus
65 | status.selected = group
66 | self:Fire("OnGroupSelected", group)
67 | end,
68 |
69 | ["OnWidthSet"] = function(self, width)
70 | local content = self.content
71 | local contentwidth = width - 26
72 | if contentwidth < 0 then
73 | contentwidth = 0
74 | end
75 | content:SetWidth(contentwidth)
76 | content.width = contentwidth
77 | end,
78 |
79 | ["OnHeightSet"] = function(self, height)
80 | local content = self.content
81 | local contentheight = height - 63
82 | if contentheight < 0 then
83 | contentheight = 0
84 | end
85 | content:SetHeight(contentheight)
86 | content.height = contentheight
87 | end,
88 |
89 | ["LayoutFinished"] = function(self, width, height)
90 | self:SetHeight((height or 0) + 63)
91 | end,
92 |
93 | ["SetDropdownWidth"] = function(self, width)
94 | self.dropdown:SetWidth(width)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local PaneBackdrop = {
102 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
103 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
104 | tile = true, tileSize = 16, edgeSize = 16,
105 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
106 | }
107 |
108 | local function Constructor()
109 | local frame = CreateFrame("Frame")
110 | frame:SetHeight(100)
111 | frame:SetWidth(100)
112 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
113 |
114 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
115 | titletext:SetPoint("TOPLEFT", 4, -5)
116 | titletext:SetPoint("TOPRIGHT", -4, -5)
117 | titletext:SetJustifyH("LEFT")
118 | titletext:SetHeight(18)
119 |
120 | local dropdown = AceGUI:Create("Dropdown")
121 | dropdown.frame:SetParent(frame)
122 | dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
123 | dropdown:SetCallback("OnValueChanged", SelectedGroup)
124 | dropdown.frame:SetPoint("TOPLEFT", -1, 0)
125 | dropdown.frame:Show()
126 | dropdown:SetLabel("")
127 |
128 | local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
129 | border:SetPoint("TOPLEFT", 0, -26)
130 | border:SetPoint("BOTTOMRIGHT", 0, 3)
131 | border:SetBackdrop(PaneBackdrop)
132 | border:SetBackdropColor(0.1,0.1,0.1,0.5)
133 | border:SetBackdropBorderColor(0.4,0.4,0.4)
134 |
135 | --Container Support
136 | local content = CreateFrame("Frame", nil, border)
137 | content:SetPoint("TOPLEFT", 10, -10)
138 | content:SetPoint("BOTTOMRIGHT", -10, 10)
139 |
140 | local widget = {
141 | frame = frame,
142 | localstatus = {},
143 | titletext = titletext,
144 | dropdown = dropdown,
145 | border = border,
146 | content = content,
147 | type = Type
148 | }
149 | for method, func in pairs(methods) do
150 | widget[method] = func
151 | end
152 | dropdown.parentgroup = widget
153 |
154 | return AceGUI:RegisterAsContainer(widget)
155 | end
156 |
157 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
158 |
--------------------------------------------------------------------------------
/tests/AceComm-3.0-pre-4.1.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 |
3 | RegisterAddonMessagePrefix = nil -- make sure we look like a pre-4.1 client (in case someone puts something in wow_api)
4 |
5 | dofile("../LibStub/LibStub.lua")
6 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
7 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
8 | dofile("../AceComm-3.0/AceComm-3.0.lua")
9 |
10 | switches = arg[1] or ""
11 |
12 | local VERBOSE,n = strfind(switches, "vv*") -- "v" anywhere in the first arg
13 | if VERBOSE then VERBOSE = n-VERBOSE+1 end -- "v"=1, "vv"=2, ...
14 |
15 |
16 |
17 |
18 | assert(RegisterAddonMessagePrefix == nil)
19 |
20 |
21 |
22 | -----------------------------------------------------------------------
23 | -----------------------------------------------------------------------
24 | -----------------------------------------------------------------------
25 | --
26 | -- Basic AceComm splitting/queueing tests
27 | --
28 |
29 | local NOCTL = strfind(switches, "t")
30 |
31 | if NOCTL then -- "t" anywhere in the first arg
32 | print("NOTE: Testing mode without ChatThrottleLib!")
33 | -- Replace ChatThrottleLib with a dummy passthrough for testing purposes
34 | function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName)
35 | self.ORIG_SendAddonMessage(prefix, text, chattype, target)
36 | end
37 | function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName)
38 | self.ORIG_SendChatMessage(text, chattype, language, destination)
39 | end
40 | end
41 |
42 |
43 | local AceComm = LibStub("AceComm-3.0")
44 |
45 | local function printf(format, ...)
46 | print(format:format(...))
47 | end
48 |
49 | local addon1 = {}
50 | local prefix1 = "Test"
51 |
52 | local addon2 = {}
53 | local prefix2 = "TestTest"
54 |
55 |
56 | local data = ""
57 | local received = {}
58 | local chartot = 0
59 |
60 | AceComm:Embed(addon1)
61 |
62 | local received1 = {}
63 | function addon1:OnCommReceived(prefix, message, distribution, sender)
64 | assert(self==addon1)
65 | assert(prefix == prefix1)
66 | assert(distribution == "RAID", dump(distribution))
67 | tinsert(received, message)
68 | tinsert(received1, message)
69 | assert(#message == #received1)
70 | assert(message == strsub(data,1,#message))
71 | chartot=chartot+#message
72 | end
73 |
74 | AceComm:Embed(addon2)
75 |
76 | local received2 = {}
77 | function addon2:OnCommReceived(prefix, message, distribution, sender)
78 | assert(self==addon2)
79 | assert(prefix == prefix2)
80 | assert(distribution == "GROUP", dump(distribution))
81 | tinsert(received, message)
82 | tinsert(received2, message)
83 | assert(#message == #received2+9)
84 | assert(message == "OogaBooga"..strsub(data,1,#message-9))
85 | chartot=chartot+#message
86 | end
87 |
88 | addon1:RegisterComm(prefix1)
89 | addon2:RegisterComm(prefix2)
90 |
91 |
92 | local MSGS=255*4 -- length 1..1000, covers all of: Single, First+Last, First+Next+Last, First+Next+Next+Last
93 | for i = 1,MSGS do
94 | data = data .. string.char(math.random(32, 255))
95 | end
96 |
97 | -- First send a boatload of data without pumping OnUpdates to CTL
98 |
99 | for i = 1,MSGS do
100 | if VERBOSE and VERBOSE>=2 then print("Sending len "..i) end
101 | addon1:SendCommMessage(prefix1, strsub(data,1,i), "RAID", nil)
102 | addon2:SendCommMessage(prefix2, "OogaBooga"..strsub(data,1,i), "GROUP", nil)
103 | end
104 |
105 | -- Now start pumping OnUpdates; there should be plenty of stuff queued in CTL, and it should all be sent in the right order!
106 | if not NOCTL then
107 | local sampledmid
108 | local esttime = ( (MSGS+20)*MSGS*2/1.62 ) / ChatThrottleLib.MAX_CPS
109 | local midpos = esttime * 0.5
110 | local latepos = esttime * 0.9
111 |
112 | local lastchartot=0
113 | local dispinterval=20
114 |
115 | local t=0
116 | if VERBOSE then
117 | print("time","rcvtot","rcv1","rcv2","cps","CTL choke")
118 | end
119 | while #received < MSGS*2 do
120 | WoWAPI_FireUpdate(t)
121 | if t%dispinterval==0 then
122 | local cps = floor((chartot-lastchartot)/dispinterval)
123 | if VERBOSE then print(t..": ",#received, #received1, #received2, cps, ChatThrottleLib.bChoking) end
124 | lastchartot=chartot
125 | if t>midpos then -- when our bandwidth isn't mostly eaten by headers and stuff
126 | assert(cps>=ChatThrottleLib.MAX_CPS*0.6 and cpsmidpos and not sampledmid then
130 | sampledmid=true
131 | assert(#received > MSGS*1.33 and #received < MSGS*1.5, dump(#received, MSGS*1.33, MSGS*1.5)) -- would be around 1 if we sent the same amount of data in each message, but we send less around the start
132 | end
133 | if t>midpos and t= #received1*0.975 and #received2 < #received1*0.99, #received1.." : "..#received2)
136 | end
137 | t=t+1
138 | end
139 |
140 | assert(t>=esttime*0.9 and t<=esttime*1.1, dump(t, esttime))
141 |
142 | assert(sampledmid)
143 |
144 | end
145 |
146 | assert(#received==MSGS*2)
147 | assert(#received1==MSGS and #received2==MSGS)
148 |
149 |
150 |
151 | -----------------------------------------------------------------------
152 | print "OK"
153 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-Label.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Label Widget
3 | Displays text and optionally an icon.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Label", 28
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local max, select, pairs = math.max, select, pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Support functions
17 | -------------------------------------------------------------------------------]]
18 |
19 | local function UpdateImageAnchor(self)
20 | if self.resizing then return end
21 | local frame = self.frame
22 | local width = frame.width or frame:GetWidth() or 0
23 | local image = self.image
24 | local label = self.label
25 | local height
26 |
27 | label:ClearAllPoints()
28 | image:ClearAllPoints()
29 |
30 | if self.imageshown then
31 | local imagewidth = image:GetWidth()
32 | if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
33 | -- image goes on top centered when less than 200 width for the text, or if there is no text
34 | image:SetPoint("TOP")
35 | label:SetPoint("TOP", image, "BOTTOM")
36 | label:SetPoint("LEFT")
37 | label:SetWidth(width)
38 | height = image:GetHeight() + label:GetStringHeight()
39 | else
40 | -- image on the left
41 | image:SetPoint("TOPLEFT")
42 | if image:GetHeight() > label:GetStringHeight() then
43 | label:SetPoint("LEFT", image, "RIGHT", 4, 0)
44 | else
45 | label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
46 | end
47 | label:SetWidth(width - imagewidth - 4)
48 | height = max(image:GetHeight(), label:GetStringHeight())
49 | end
50 | else
51 | -- no image shown
52 | label:SetPoint("TOPLEFT")
53 | label:SetWidth(width)
54 | height = label:GetStringHeight()
55 | end
56 |
57 | -- avoid zero-height labels, since they can used as spacers
58 | if not height or height == 0 then
59 | height = 1
60 | end
61 |
62 | self.resizing = true
63 | frame:SetHeight(height)
64 | frame.height = height
65 | self.resizing = nil
66 | end
67 |
68 | --[[-----------------------------------------------------------------------------
69 | Methods
70 | -------------------------------------------------------------------------------]]
71 | local methods = {
72 | ["OnAcquire"] = function(self)
73 | -- set the flag to stop constant size updates
74 | self.resizing = true
75 | -- height is set dynamically by the text and image size
76 | self:SetWidth(200)
77 | self:SetText()
78 | self:SetImage(nil)
79 | self:SetImageSize(16, 16)
80 | self:SetColor()
81 | self:SetFontObject()
82 | self:SetJustifyH("LEFT")
83 | self:SetJustifyV("TOP")
84 |
85 | -- reset the flag
86 | self.resizing = nil
87 | -- run the update explicitly
88 | UpdateImageAnchor(self)
89 | end,
90 |
91 | -- ["OnRelease"] = nil,
92 |
93 | ["OnWidthSet"] = function(self, width)
94 | UpdateImageAnchor(self)
95 | end,
96 |
97 | ["SetText"] = function(self, text)
98 | self.label:SetText(text)
99 | UpdateImageAnchor(self)
100 | end,
101 |
102 | ["SetColor"] = function(self, r, g, b)
103 | if not (r and g and b) then
104 | r, g, b = 1, 1, 1
105 | end
106 | self.label:SetVertexColor(r, g, b)
107 | end,
108 |
109 | ["SetImage"] = function(self, path, ...)
110 | local image = self.image
111 | image:SetTexture(path)
112 |
113 | if image:GetTexture() then
114 | self.imageshown = true
115 | local n = select("#", ...)
116 | if n == 4 or n == 8 then
117 | image:SetTexCoord(...)
118 | else
119 | image:SetTexCoord(0, 1, 0, 1)
120 | end
121 | else
122 | self.imageshown = nil
123 | end
124 | UpdateImageAnchor(self)
125 | end,
126 |
127 | ["SetFont"] = function(self, font, height, flags)
128 | if not self.fontObject then
129 | self.fontObject = CreateFont("AceGUI30LabelFont" .. AceGUI:GetNextWidgetNum(Type))
130 | end
131 | self.fontObject:SetFont(font, height, flags)
132 | self:SetFontObject(self.fontObject)
133 | end,
134 |
135 | ["SetFontObject"] = function(self, font)
136 | self.label:SetFontObject(font or GameFontHighlightSmall)
137 | UpdateImageAnchor(self)
138 | end,
139 |
140 | ["SetImageSize"] = function(self, width, height)
141 | self.image:SetWidth(width)
142 | self.image:SetHeight(height)
143 | UpdateImageAnchor(self)
144 | end,
145 |
146 | ["SetJustifyH"] = function(self, justifyH)
147 | self.label:SetJustifyH(justifyH)
148 | end,
149 |
150 | ["SetJustifyV"] = function(self, justifyV)
151 | self.label:SetJustifyV(justifyV)
152 | end,
153 | }
154 |
155 | --[[-----------------------------------------------------------------------------
156 | Constructor
157 | -------------------------------------------------------------------------------]]
158 | local function Constructor()
159 | local frame = CreateFrame("Frame", nil, UIParent)
160 | frame:Hide()
161 |
162 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
163 | local image = frame:CreateTexture(nil, "BACKGROUND")
164 |
165 | -- create widget
166 | local widget = {
167 | label = label,
168 | image = image,
169 | frame = frame,
170 | type = Type
171 | }
172 | for method, func in pairs(methods) do
173 | widget[method] = func
174 | end
175 |
176 | return AceGUI:RegisterAsWidget(widget)
177 | end
178 |
179 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
180 |
--------------------------------------------------------------------------------
/tests/AceTimer-3.0-test1.lua:
--------------------------------------------------------------------------------
1 | -- Test1: Tests basic functionality and upgrading of AceTimer
2 |
3 | dofile("wow_api.lua")
4 | dofile("LibStub.lua")
5 |
6 | local MAJOR = "AceTimer-3.0"
7 |
8 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
9 |
10 | local AceTimer,minor = LibStub:GetLibrary(MAJOR)
11 | _G.AceTimer=AceTimer
12 |
13 | -----------------------------------------------------------------------
14 | -- Test embedding
15 |
16 | local obj={}
17 | AceTimer:Embed(obj)
18 |
19 | assert(type(obj.ScheduleTimer)=="function")
20 | assert(type(obj.ScheduleRepeatingTimer)=="function")
21 | assert(type(obj.CancelTimer)=="function")
22 | assert(type(obj.CancelAllTimers)=="function")
23 |
24 |
25 |
26 | -----------------------------------------------------------------------
27 | -- Test basic registering, both ways
28 |
29 | t1s = 0
30 | function obj:Timer1(arg)
31 | assert(self==obj)
32 | assert(arg=="t1")
33 | t1s = t1s + 1
34 | end
35 |
36 | t2s = 0
37 | function Timer2(arg)
38 | assert(arg=="t2")
39 | t2s = t2s + 1
40 | end
41 |
42 | function obj:Timer3()
43 | assert(false) -- This should never run!
44 | end
45 |
46 | t4s=0
47 | t5s=0
48 | local function Timer4_5(arg)
49 | assert(arg=="t4s" or arg=="t5s", dump(arg))
50 | _G[arg] = _G[arg] + 1
51 | end
52 | function obj:Timer4(arg)
53 | assert(self==obj)
54 | Timer4_5(arg)
55 | end
56 |
57 | -- 3 repeating timers:
58 | timer1 = obj:ScheduleRepeatingTimer("Timer1", 1, "t1")
59 | timer2 = obj:ScheduleRepeatingTimer(Timer2, 2, "t2")
60 | timer3 = obj:ScheduleRepeatingTimer("Timer3", 3, "t3")
61 |
62 | -- 2 single shot timers:
63 | timer4 = obj:ScheduleTimer("Timer4", 1, "t4s")
64 | timer5 = obj.ScheduleTimer("myObj", Timer4_5, 2, "t5s") -- string as self
65 |
66 |
67 | t3s = 0
68 | function obj:Timer3(arg) -- This should be the one to run, not the old Timer3
69 | assert(self==obj)
70 | assert(arg=="t3")
71 | t3s = t3s + 1
72 | end
73 |
74 |
75 | -----------------------------------------------------------------------
76 | -- Now do some basic tests of timers running at the right time and
77 | -- the right amount of times
78 |
79 |
80 | WoWAPI_FireUpdate(0)
81 | assert(t1s==0 and t2s==0 and t3s==0 and t4s==0 and t5s==0)
82 |
83 | WoWAPI_FireUpdate(0.99)
84 | assert(t1s==0 and t2s==0 and t3s==0 and t4s==0 and t5s==0)
85 |
86 | WoWAPI_FireUpdate(1.00)
87 | assert(t1s==1 and t2s==0 and t3s==0 and t4s==1 and t5s==0, dump(t1s,t2s,t3s,t4s,t5s))
88 |
89 | WoWAPI_FireUpdate(1.99)
90 | assert(t1s==1 and t2s==0 and t3s==0 and t4s==1 and t5s==0)
91 |
92 | WoWAPI_FireUpdate(2.5)
93 | assert(t1s==2 and t2s==1 and t3s==0 and t4s==1 and t5s==1)
94 |
95 | WoWAPI_FireUpdate(2.99)
96 | assert(t1s==2 and t2s==1 and t3s==0)
97 |
98 | WoWAPI_FireUpdate(3.099)
99 | assert(t1s==3 and t2s==1, t2s and t3s==1, t3s)
100 |
101 | WoWAPI_FireUpdate(6.000)
102 | assert(t3s==2)
103 |
104 | assert(t4s==1 and t5s==1) -- make sure our single shot timers haven't run more than once
105 |
106 |
107 |
108 | t6s=0
109 | obj:ScheduleTimer(function() t6s=t6s+1 end, 1) -- fire up a single oneshot timer to live past our upgrade below
110 |
111 |
112 | -----------------------------------------------------------------------
113 | -- Screw up our mixins, pretend to have an older acetimer loaded, and reload acetimer
114 |
115 | obj.ScheduleTimer = 12345
116 |
117 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
118 |
119 | assert(obj.ScheduleTimer == 12345) -- shouldn't have gotten replaced yet
120 |
121 | LibStub.minors[MAJOR] = LibStub.minors[MAJOR] - 1
122 |
123 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
124 |
125 | assert(type(obj.ScheduleTimer)=="function") -- should have been replaced now
126 |
127 |
128 | -----------------------------------------------------------------------
129 | -- Test that timers still live
130 |
131 | t1s, t2s, t3s, t4s, t5s = 0,0,0,0,0
132 |
133 | WoWAPI_FireUpdate(6.5)
134 | assert(t1s==0 and t2s==0 and t3s==0 and t4s==0 and t5s==0 and t6s==0)
135 |
136 | WoWAPI_FireUpdate(7.7)
137 | assert(t1s==1 and t2s==0 and t3s==0 and t4s==0 and t5s==0 and t6s==1, dump(t1s,t2s,t3s,t4s,t5s,t6s))
138 |
139 | WoWAPI_FireUpdate(9.8)
140 | assert(t1s==2 and t2s==1 and t3s==1 and t4s==0 and t5s==0 and t6s==1) -- NOTE: t1s will only fire ONCE now, since we had a >1.99s lag!
141 |
142 |
143 |
144 | -----------------------------------------------------------------------
145 | -- Test cancelling
146 | -- - test right and wrong 'self'
147 | -- - test cancelling from within the timer
148 |
149 | t1s, t2s, t3s, t4s, t5s, t6s = 0,0,0,0,0,0
150 |
151 | assert(not AceTimer:CancelTimer(timer1, true)) -- wrong self, shouldnt cancel anything
152 |
153 | assert(obj:CancelTimer(timer1)) -- right self - cancel timer1
154 |
155 | WoWAPI_FireUpdate(10.01)
156 | assert(t1s==0 and t2s==1) -- timer 2 should still work
157 |
158 | obj.Timer3 = function()
159 | t3s=t3s+1
160 | t3cancelled=true
161 | assert(obj:CancelTimer(timer3))
162 | end
163 |
164 | WoWAPI_FireUpdate(13.01)
165 | assert(t1s==0 and t2s==2 and t3s==1)
166 | assert(t3cancelled)
167 |
168 | WoWAPI_FireUpdate(16.01)
169 | assert(t1s==0 and t2s==3 and t3s==1, t1s..t2s..t3s)
170 | assert(t3cancelled)
171 |
172 |
173 | t1s, t2s, t3s, t4s, t5s = 0,0,0,0,0
174 |
175 | obj:CancelAllTimers()
176 |
177 | local i = 17
178 | local e = i + AceTimer.debug.BUCKETS / AceTimer.debug.HZ * 5 -- 5 full loops of all buckets
179 | while i < e do
180 | i=i+math.random()
181 | WoWAPI_FireUpdate(i) -- long time in the future
182 | end
183 | assert(t1s==0 and t2s==0 and t3s==0 and t4s==0 and t5s==0 and t6s==0) -- nothing should have fired
184 |
185 |
186 | -----------------------------------------------------------------------
187 | --
188 |
189 | for i=1,AceTimer.debug.BUCKETS do
190 | if AceTimer.hash[i]~=false then
191 | error("AceTimer.hash["..i.."] was '"..tostring(AceTimer.hash[i]).."' - expected false")
192 | end
193 | end
194 |
195 | -----------------------------------------------------------------------
196 |
197 | print "OK"
198 |
--------------------------------------------------------------------------------
/AceLocale-3.0/AceLocale-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
2 | -- @class file
3 | -- @name AceLocale-3.0
4 | -- @release $Id$
5 | local MAJOR,MINOR = "AceLocale-3.0", 6
6 |
7 | local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
8 |
9 | if not AceLocale then return end -- no upgrade needed
10 |
11 | -- Lua APIs
12 | local assert, tostring, error = assert, tostring, error
13 | local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
14 |
15 | local gameLocale = GetLocale()
16 | if gameLocale == "enGB" then
17 | gameLocale = "enUS"
18 | end
19 |
20 | AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
21 | AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
22 |
23 | -- This metatable is used on all tables returned from GetLocale
24 | local readmeta = {
25 | __index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
26 | rawset(self, key, key) -- only need to see the warning once, really
27 | geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
28 | return key
29 | end
30 | }
31 |
32 | -- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
33 | local readmetasilent = {
34 | __index = function(self, key) -- requesting totally unknown entries: return key
35 | rawset(self, key, key) -- only need to invoke this function once
36 | return key
37 | end
38 | }
39 |
40 | -- Remember the locale table being registered right now (it gets set by :NewLocale())
41 | -- NOTE: Do never try to register 2 locale tables at once and mix their definition.
42 | local registering
43 |
44 | -- local assert false function
45 | local assertfalse = function() assert(false) end
46 |
47 | -- This metatable proxy is used when registering nondefault locales
48 | local writeproxy = setmetatable({}, {
49 | __newindex = function(self, key, value)
50 | rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
51 | end,
52 | __index = assertfalse
53 | })
54 |
55 | -- This metatable proxy is used when registering the default locale.
56 | -- It refuses to overwrite existing values
57 | -- Reason 1: Allows loading locales in any order
58 | -- Reason 2: If 2 modules have the same string, but only the first one to be
59 | -- loaded has a translation for the current locale, the translation
60 | -- doesn't get overwritten.
61 | --
62 | local writedefaultproxy = setmetatable({}, {
63 | __newindex = function(self, key, value)
64 | if not rawget(registering, key) then
65 | rawset(registering, key, value == true and key or value)
66 | end
67 | end,
68 | __index = assertfalse
69 | })
70 |
71 | --- Register a new locale (or extend an existing one) for the specified application.
72 | -- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
73 | -- game locale.
74 | -- @paramsig application, locale[, isDefault[, silent]]
75 | -- @param application Unique name of addon / module
76 | -- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
77 | -- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
78 | -- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
79 | -- @usage
80 | -- -- enUS.lua
81 | -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
82 | -- L["string1"] = true
83 | --
84 | -- -- deDE.lua
85 | -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
86 | -- if not L then return end
87 | -- L["string1"] = "Zeichenkette1"
88 | -- @return Locale Table to add localizations to, or nil if the current locale is not required.
89 | function AceLocale:NewLocale(application, locale, isDefault, silent)
90 |
91 | -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
92 | local activeGameLocale = GAME_LOCALE or gameLocale
93 |
94 | local app = AceLocale.apps[application]
95 |
96 | if silent and app and getmetatable(app) ~= readmetasilent then
97 | geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
98 | end
99 |
100 | if not app then
101 | if silent=="raw" then
102 | app = {}
103 | else
104 | app = setmetatable({}, silent and readmetasilent or readmeta)
105 | end
106 | AceLocale.apps[application] = app
107 | AceLocale.appnames[app] = application
108 | end
109 |
110 | if locale ~= activeGameLocale and not isDefault then
111 | return -- nop, we don't need these translations
112 | end
113 |
114 | registering = app -- remember globally for writeproxy and writedefaultproxy
115 |
116 | if isDefault then
117 | return writedefaultproxy
118 | end
119 |
120 | return writeproxy
121 | end
122 |
123 | --- Returns localizations for the current locale (or default locale if translations are missing).
124 | -- Errors if nothing is registered (spank developer, not just a missing translation)
125 | -- @param application Unique name of addon / module
126 | -- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
127 | -- @return The locale table for the current language.
128 | function AceLocale:GetLocale(application, silent)
129 | if not silent and not AceLocale.apps[application] then
130 | error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
131 | end
132 | return AceLocale.apps[application]
133 | end
134 |
--------------------------------------------------------------------------------
/tests/AceConfigCmd-3.0.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceConsole-3.0/AceConsole-3.0.lua")
5 | dofile("../AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua")
6 | dofile("../AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua")
7 |
8 | local ccmd = assert(LibStub("AceConfigCmd-3.0"))
9 | local creg = assert(LibStub("AceConfigRegistry-3.0"))
10 |
11 |
12 | local app={}
13 |
14 | -- helper: counts of what's been execd
15 | local n = setmetatable({}, { __index = function(self,k) return 0 end })
16 | function n:clear()
17 | for k,v in pairs(self) do
18 | if k~="clear" then
19 | self[k]=nil
20 | end
21 | end
22 | end
23 |
24 |
25 | ----- set / get on application object
26 |
27 | function app:get_toggle(info, ...)
28 | assert(self==app)
29 | assert(select("#",...)==0)
30 |
31 | n.get_toggle = n.get_toggle + 1
32 | return true
33 | end
34 |
35 | function app:set_toggle(info, ...)
36 | assert(self==app, "Expected self=="..tostring(app)..", got "..tostring(self))
37 | assert(select("#",...)==1)
38 | local b = select(1,...)
39 | n.set_toggle = n.set_toggle + 1
40 | assert(b==false)
41 | end
42 |
43 |
44 | --- set / get / validate as function refs
45 |
46 | function makefunc(name)
47 | _G[name] = function(info,...)
48 | assert(type(info)=="table")
49 | assert(#info>=1)
50 | n[name] = n[name] + 1
51 | return _G["_"..name](info,...)
52 | end
53 | end
54 |
55 | makefunc("set_base")
56 | makefunc("get_base")
57 | makefunc("validate_base")
58 |
59 |
60 |
61 |
62 | ---------------- the option table!!
63 |
64 | local opts = {
65 | type = "group",
66 | get = get_base, -- tests inheritance by declaring it at the bottom
67 | set = set_base,
68 | validate = validate_base,
69 |
70 | args = {
71 | input = {
72 | type="input",
73 | name="Input",
74 | desc="Input Desc",
75 | validate = false, -- tests removing inherited validate
76 | },
77 | toggle = {
78 | type="toggle",
79 | name="Toggle",
80 | desc="Toggle Desc",
81 | handler=app, -- tests "handler" arg
82 | get = "get_toggle", -- tests overriding, and membernames
83 | set = "set_toggle",
84 | },
85 | plugcmd = { -- this should never be used, we should use the plugin!
86 | name="PlugCmdOrig",
87 | desc="YOU SHOULD NOT SEE THIS",
88 | type="toggle",
89 | set = function() assert(false) end,
90 | get = function() assert(false) end,
91 | }
92 | },
93 |
94 | plugins = { -- test plugins
95 | plugin1 = {
96 | plugcmd = {
97 | name="PluggedCmd",
98 | desc="Woohoo",
99 | type="toggle",
100 | },
101 | plugcmd2 = {
102 | name="PluggedCmd2",
103 | desc="WooTwo",
104 | type="toggle",
105 | }
106 | },
107 | plugin2 = {
108 | -- empty, shouldnt cause errors
109 | },
110 | plugin3 = {
111 | p3cmd = {
112 | name="Plugin3Cmd",
113 | desc="WooThree",
114 | type="toggle",
115 | },
116 | }
117 |
118 | }
119 | }
120 |
121 | creg:RegisterOptionsTable("testapp", opts)
122 |
123 | assert(creg:GetOptionsTable("testapp")("cmd","foo-1") == opts)
124 | assert(creg:GetOptionsTable("testapp","cmd","foo-1") == opts)
125 |
126 |
127 | -- User error handler
128 | local expect = {} -- list of strings to expect
129 | function ChatFrame1.AddMessage(self, txt)
130 | local expstr = tremove(expect)
131 | assert(expstr, "Unexpected output: <"..txt..">")
132 | assert(string.match(txt,expstr), "Got output <"..txt..">, expected <"..expstr..">")
133 | end
134 |
135 |
136 |
137 | --------------- test "/test toggle" (via handler:methodname)
138 |
139 | function _validate_base() end -- noop
140 |
141 | tinsert(expect, "/test toggle : 'thisshoulderror' %- expected 'on' or 'off', or no argument to toggle.")
142 | ccmd:HandleCommand("test","testapp","toggle thisshoulderror") -- shouldn't work
143 | assert(n.get_toggle==0)
144 | assert(n.set_toggle==0)
145 | assert(n.validate_base==0)
146 | assert(table.getn(expect)==0)
147 |
148 | n:clear()
149 | ccmd:HandleCommand("test","testapp","toggle off")
150 | assert(n.get_toggle==0)
151 | assert(n.set_toggle==1)
152 | assert(n.validate_base==1)
153 |
154 | n:clear()
155 | ccmd:HandleCommand("test","testapp","toggle")
156 | assert(n.get_toggle==1)
157 | assert(n.set_toggle==1)
158 | assert(n.validate_base==1)
159 |
160 | function _validate_base(info, ...)
161 | return "THIS FAILS"
162 | end
163 | n:clear()
164 | tinsert(expect, "/test toggle : 'on' %- THIS FAILS")
165 | ccmd:HandleCommand("test","testapp","toggle on") -- "on" since it'll error if it reachest the set handler (it only accepts false)
166 | assert(n.get_base==0)
167 | assert(n.set_base==0)
168 | assert(n.validate_base==1)
169 |
170 |
171 |
172 | -------------- test "/test input" (via funcrefs)
173 |
174 | function _set_base(info,...)
175 | assert(select("#",...)==1)
176 | assert(#info==1)
177 | assert(info[0]=="test")
178 | assert(info[1]=="input")
179 | local a1 = ...
180 | assert(a1=="")
181 | end
182 |
183 | n:clear()
184 | ccmd:HandleCommand("test","testapp","input")
185 | assert(n.get_base==0)
186 | assert(n.validate_base==0)
187 | assert(n.set_base==1)
188 |
189 |
190 | function _set_base(info, ...)
191 | assert(...=="hi2u woo ",dump(...))
192 | end
193 | ccmd:HandleCommand("test","testapp","input hi2u woo ")
194 |
195 |
196 |
197 |
198 | -----------------------------------------------------------------------
199 |
200 | local seen = {
201 | [".*Arguments to.*"]=0,
202 | ["input.*Input Desc"]=0,
203 | ["toggle.*Toggle Desc"]=0,
204 | ["plugcmd.*Woohoo"]=0,
205 | ["plugcmd2.*WooTwo"]=0,
206 | ["p3cmd.*WooThree"]=0,
207 | }
208 | function ChatFrame1.AddMessage(self, txt)
209 | local ok
210 | for k,v in pairs(seen) do
211 | if strmatch(txt, k) then
212 | seen[k]=seen[k]+1
213 | ok=true
214 | break
215 | end
216 | end
217 | assert(ok, "Did not expect to see "..format("%q",txt))
218 | end
219 |
220 | ccmd:HandleCommand("test","testapp","")
221 |
222 | for k,v in pairs(seen) do
223 | assert(v==1, "Expected to see <"..k.."> once. Saw it "..v.." times.")
224 | end
225 |
226 | -----------------------------------------------------------------------
227 | print "OK"
228 |
--------------------------------------------------------------------------------
/tests/AceTimer-3.0-ACE94.lua:
--------------------------------------------------------------------------------
1 | -- Test for ACE-94: memory reclaiming of table indices
2 |
3 | dofile("wow_api.lua")
4 | dofile("LibStub.lua")
5 |
6 | local MAJOR = "AceTimer-3.0"
7 |
8 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
9 |
10 | local AceTimer,minor = LibStub:GetLibrary(MAJOR)
11 |
12 | local function dummy() end
13 |
14 | local VERBOSE = strmatch(arg[1] or "", "v")
15 |
16 | -- Initial memory that we have to include...
17 |
18 | local objs={}
19 | for n=1,3 do
20 | objs[n] = {}
21 | end
22 |
23 | WoWAPI_FireUpdate(GetTime()+100)
24 |
25 | -----------------------------------------------------------------------
26 | -- Get "empty" memory count
27 |
28 | collectgarbage("collect")
29 | local mem = collectgarbage("count")
30 |
31 |
32 |
33 | -----------------------------------------------------------------------
34 | -- Run the whole test five times to make sure the cleaner keeps working after a loop
35 |
36 | for LOOP=1,5 do
37 |
38 | if VERBOSE then print("\n------------- Loop "..LOOP) end
39 |
40 | -----------------------------------------------------------------------
41 | -- Schedule a boatload of timers
42 |
43 | for _,obj in pairs(objs) do
44 | for t=1,1000 do
45 | AceTimer.ScheduleTimer(obj, dummy, 1)
46 | end
47 | end
48 |
49 | collectgarbage("collect")
50 | if VERBOSE then print(collectgarbage("count") - mem.."KB used - everything live") end
51 | -- About 688K in original test
52 |
53 |
54 |
55 | -----------------------------------------------------------------------
56 | -- Cancel them all again
57 |
58 | for _,obj in pairs(objs) do
59 | AceTimer.CancelAllTimers(obj)
60 | end
61 |
62 | -- .. and let them get removed from hash buckets over time
63 | WoWAPI_FireUpdate(GetTime()+100)
64 |
65 | collectgarbage("collect")
66 | local idxwaste = collectgarbage("count") - mem
67 | if VERBOSE then print(idxwaste.."KB used - this is table index waste. Expecting ~110 KB.") end
68 |
69 | -- We should be wasting about 110K here (warnmsg in original test)
70 | -- 1000 timers * 3 objects * ~40 bytes per index = ~120KB. Sounds about right.
71 | assert(idxwaste>80 and idxwaste<160, dump(idxwaste))
72 |
73 |
74 |
75 | -----------------------------------------------------------------------
76 | -- Now start firing PLAYER_REGEN_ENABLED and watch memory decrease
77 |
78 | -- Clean up 2 thirds
79 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
80 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
81 |
82 | -- See if 1 third remains
83 | collectgarbage("collect")
84 | local thirdwaste = collectgarbage("count") - mem
85 |
86 | assert(thirdwaste > idxwaste/3*0.9 and thirdwaste < idxwaste/3*1.1, dump(thirdwaste, idxwaste))
87 |
88 | -- Clean up last third
89 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
90 |
91 |
92 | -----------------------------------------------------------------------
93 | -- We should now be back to near 0 mem consumption
94 |
95 | collectgarbage("collect")
96 | local endresult = collectgarbage("count") - mem
97 | if VERBOSE then print(endresult.."KB used - should be nearly clean") end
98 | -- I'm getting ~2.5K waste from system total, probably something eating a bit more after being run once, not going to go hunting for it
99 | -- Loops 2..n keep using the same total.
100 | assert(endresult>0 and endresult<10)
101 |
102 |
103 | end -- for LOOP=1,5
104 |
105 |
106 | -----------------------------------------------------------------------
107 | -- Test the excessive timer count warning system
108 | -- Also make sure the cleaner obeys our minimum operation criteria and doesn't run too often
109 | -- (Cleaner and warning runs at the same time)
110 |
111 | if VERBOSE then print("\n------------- Testing excessive timer count warnings") end
112 |
113 | local obj = setmetatable({}, {
114 | __tostring = function(self)
115 | return "MyTestObj"
116 | end
117 | })
118 |
119 | assert(AceTimer.debug.BUCKETS < 1000) -- .BUCKETS is the warning limit
120 | for t=1,1000 do
121 | AceTimer.ScheduleTimer(obj, dummy, 1)
122 | end
123 |
124 | local warnmsg
125 | local numwarnmsgs=0
126 | function ChatFrame1:AddMessage(msg)
127 | if VERBOSE then print("Warning message emitted: <"..msg..">") end
128 | warnmsg = msg
129 | numwarnmsgs=numwarnmsgs+1
130 | end
131 |
132 | for _ in pairs(AceTimer.selfs) do
133 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
134 | end
135 | assert(numwarnmsgs==1, dump(numwarnmsgs))
136 | assert(strmatch(warnmsg, "MyTestObj.*has 100[0-9] live timers"), dump(warnmsg, msg)) -- it won't be 1000 since __ops etc gets counted. it'll be a little more.
137 |
138 | -- Now it shouldn't clean&warn again since there are no operations on the table
139 | numwarnmsgs=0
140 | for _ in pairs(AceTimer.selfs) do
141 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
142 | end
143 | assert(numwarnmsgs==0)
144 |
145 | -- Artificially inflate __ops somewhat, still shouldn't warn
146 | AceTimer.selfs[obj].__ops = 10
147 | numwarnmsgs=0
148 | for _ in pairs(AceTimer.selfs) do
149 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
150 | end
151 | assert(numwarnmsgs==0)
152 |
153 | -- Artificially inflate __ops A LOT, now it should warn again. Once.
154 | AceTimer.selfs[obj].__ops = 1000000
155 | numwarnmsgs=0
156 | for LOOP=1,20 do
157 | for _ in pairs(AceTimer.selfs) do
158 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
159 | end
160 | end
161 | assert(numwarnmsgs==1)
162 |
163 |
164 | -----------------------------------------------------------------------
165 | -- Test a fencepost case: only one addon. That one addon should be
166 | -- checked for every PLAYER_REGEN_ENABLED.
167 |
168 | LibStub.libs[MAJOR] = nil
169 | LibStub.minors[MAJOR] = nil
170 | dofile("../"..MAJOR.."/"..MAJOR..".lua")
171 |
172 | local AceTimer,minor = LibStub:GetLibrary(MAJOR)
173 |
174 | assert(AceTimer.debug.BUCKETS < 1000) -- .BUCKETS is the warning limit
175 | for t=1,1000 do
176 | AceTimer.ScheduleTimer(obj, dummy, 1)
177 | end
178 |
179 | for LOOP=1,3 do
180 | numwarnmsgs=0
181 | AceTimer.selfs[obj].__ops = 1000000
182 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
183 | assert(numwarnmsgs==1)
184 | end
185 |
186 | for LOOP=1,3 do
187 | numwarnmsgs=0
188 | -- no __ops increase, nothing should be checked
189 | WoWAPI_FireEvent("PLAYER_REGEN_ENABLED")
190 | assert(numwarnmsgs==0)
191 | end
192 |
193 |
194 |
195 |
196 | -----------------------------------------------------------------------
197 | print "OK"
198 |
--------------------------------------------------------------------------------
/tests/AceDB-3.0-defaults.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceDB-3.0/AceDB-3.0.lua")
5 | dofile("serialize.lua")
6 |
7 | -- Test the defaults system
8 | do
9 |
10 | local defaults = {
11 | profile = {
12 | singleEntry = "singleEntry",
13 | tableEntry = {
14 | tableDefault = "tableDefault",
15 | },
16 | starTest = {
17 | ["*"] = {
18 | starDefault = "starDefault",
19 | },
20 | sibling = {
21 | siblingDefault = "siblingDefault",
22 | },
23 | siblingDeriv = {
24 | starDefault = "not-so-starDefault",
25 | },
26 | },
27 | doubleStarTest = {
28 | ["**"] = {
29 | doubleStarDefault = "doubleStarDefault",
30 | },
31 | sibling = {
32 | siblingDefault = "siblingDefault",
33 | },
34 | siblingDeriv = {
35 | doubleStarDefault = "overruledDefault",
36 | }
37 | },
38 | starTest2 = {
39 | ["*"] = "fun",
40 | sibling = "notfun",
41 | }
42 | },
43 | }
44 |
45 | local db = LibStub("AceDB-3.0"):New("MyDB", defaults)
46 | assert(db.profile.singleEntry == "singleEntry")
47 | assert(db.profile.tableEntry.tableDefault == "tableDefault")
48 | assert(db.profile.starTest.randomkey.starDefault == "starDefault")
49 | assert(db.profile.starTest.sibling.siblingDefault == "siblingDefault")
50 | assert(db.profile.starTest.sibling.starDefault == nil)
51 | assert(db.profile.doubleStarTest.randomkey.doubleStarDefault == "doubleStarDefault")
52 | assert(db.profile.doubleStarTest.sibling.siblingDefault == "siblingDefault")
53 | assert(db.profile.doubleStarTest.sibling.doubleStarDefault == "doubleStarDefault")
54 | assert(db.profile.doubleStarTest.siblingDeriv.doubleStarDefault == "overruledDefault")
55 | assert(db.profile.starTest2.randomkey == "fun")
56 | assert(db.profile.starTest2.sibling == "notfun")
57 |
58 | db.profile.doubleStarTest.siblingDeriv.doubleStarDefault = "doubleStarDefault"
59 | db.profile.starTest2.randomkey = "notfun"
60 | db.profile.starTest2.randomkey2 = "fun"
61 | db.profile.starTest2.sibling = "fun"
62 |
63 | WoWAPI_FireEvent("PLAYER_LOGOUT")
64 |
65 | assert(db.profile.singleEntry == nil)
66 | assert(db.profile.tableEntry == nil)
67 | assert(db.profile.starTest == nil)
68 | assert(db.profile.doubleStarTest.randomkey == nil)
69 | assert(db.profile.doubleStarTest.siblingDeriv.doubleStarDefault == "doubleStarDefault")
70 | assert(db.profile.starTest2.randomkey == "notfun")
71 | assert(db.profile.starTest2.randomkey2 == nil)
72 | assert(db.profile.starTest2.sibling == "fun")
73 | end
74 |
75 | do
76 | local defaultTest = {
77 | profile = {
78 | units = {
79 | ["**"] = {
80 | test = 2
81 | },
82 | ["player"] = {
83 | },
84 | ["pet"] = {
85 | test = 3
86 | },
87 | ["bug"] = {
88 | test = 3,
89 | },
90 | }
91 | }
92 | }
93 |
94 | local bugdb = {
95 | ["profileKeys"] = {
96 | ["player - Realm Name"] = "player - Realm Name",
97 | },
98 | ["profiles"] = {
99 | ["player - Realm Name"] = {
100 | ["units"] = {
101 | ["player"] = {
102 | },
103 | ["pet"] = {
104 | },
105 | ["focus"] = {
106 | },
107 | bug = "bug",
108 | },
109 | },
110 | },
111 | }
112 |
113 | local data = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
114 |
115 | assert(data.profile.units["player"].test == 2)
116 | assert(data.profile.units["pet"].test == 3)
117 | assert(data.profile.units["focus"].test == 2)
118 | assert(type(data.profile.units.bug) == "string")
119 | WoWAPI_FireEvent("PLAYER_LOGOUT")
120 | end
121 |
122 | do
123 | local defaultTest = {
124 | profile = {
125 | units = {
126 | ["*"] = {
127 | test = 2
128 | },
129 | ["player"] = {
130 | }
131 | }
132 | }
133 | }
134 |
135 | local bugdb = {
136 | ["profileKeys"] = {
137 | ["player - Realm Name"] = "player - Realm Name",
138 | },
139 | ["profiles"] = {
140 | ["player - Realm Name"] = {
141 | ["units"] = {
142 | ["player"] = {
143 | },
144 | ["pet"] = {
145 | },
146 | },
147 | },
148 | },
149 | }
150 |
151 | local data = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
152 |
153 | assert(data.profile.units["player"].test == nil)
154 | assert(data.profile.units["pet"].test == 2)
155 | assert(data.profile.units["focus"].test == 2)
156 | end
157 |
158 | do
159 | local defaultTest = {
160 | profile = {
161 | foo = {
162 | ["*"] = {
163 | plyf = true,
164 | },
165 | }
166 | }
167 | }
168 |
169 |
170 | local bugdb = {
171 | ["profileKeys"] = {
172 | ["player - Realm Name"] = "player - Realm Name",
173 | },
174 | ["profiles"] = {
175 | ["player - Realm Name"] = {
176 | ["foo"] = {
177 | hopla = 42,
178 | },
179 | },
180 | },
181 | }
182 |
183 | local data = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
184 |
185 | assert(data.profile.foo.hopla == 42)
186 | end
187 |
188 | do
189 | local defaultTest = {
190 | profile = {
191 | ['**'] = {
192 | ['*'] = {
193 | stuff = 5,
194 | stuff2 = {
195 | ['**'] = {
196 | a = 4,
197 | },
198 | },
199 | },
200 | },
201 | stuff2 = {
202 | blu = {
203 | stuff = 6,
204 | stuff2 = {
205 | b = {
206 | a = 5
207 | },
208 | },
209 | },
210 | },
211 | },
212 | }
213 |
214 | local bugdb = {}
215 | local data = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
216 | data.profile.stuff2.blu.stuff = 5
217 | data.profile.stuff2.blu.stuff2.b.a = 4
218 | data:RegisterDefaults()
219 |
220 | local data2 = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
221 |
222 | assert(data2.profile.stuff2.blu.stuff == 5)
223 | assert(data2.profile.stuff2.blu.stuff2.b.a == 4)
224 | end
225 |
226 | do
227 | local defaultTest = {
228 | profile = {
229 | boo = {
230 | [true] = "true",
231 | [false] = "false",
232 | },
233 | }
234 | }
235 |
236 | local bugdb = {}
237 | local data = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
238 | data.profile.boo[true] = "not so true"
239 | data.profile.boo[false] = "not so false"
240 | WoWAPI_FireEvent("PLAYER_LOGOUT")
241 |
242 | local data2 = LibStub("AceDB-3.0"):New(bugdb, defaultTest)
243 | assert(data2.profile.boo[true] == "not so true")
244 | assert(data2.profile.boo[false] == "not so false")
245 | end
246 |
247 | do
248 | local db = {}
249 | -- test case for ticket 66
250 | local defaults = {
251 | profile = {
252 | Positions = {
253 | ["**"] = {
254 | point = "CENTER", relativeTo = "UIParent", relativePoint = "CENTER", xOfs = 0, yOfs = 0
255 | },
256 | },
257 | },
258 | }
259 |
260 | local data = LibStub("AceDB-3.0"):New(db, defaults)
261 |
262 | local v1 = data.profile.Positions.foo
263 |
264 | defaults.profile.Positions["TestFrame"] = {
265 | point = "TOP",
266 | relativeTo = "UIParent",
267 | relativePoint = "TOP",
268 | xOfs = 100,
269 | yOfs = 200,
270 | }
271 |
272 | data:RegisterDefaults(defaults)
273 | assert(data.profile.Positions.TestFrame.xOfs == 100)
274 | end
275 |
--------------------------------------------------------------------------------
/tests/AceDB-3.0.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceDB-3.0/AceDB-3.0.lua")
5 | dofile("serialize.lua")
6 |
7 | -- Test the defaults system
8 | do
9 |
10 | local defaults = {
11 | profile = {
12 | singleEntry = "singleEntry",
13 | tableEntry = {
14 | tableDefault = "tableDefault",
15 | },
16 | starTest = {
17 | ["*"] = {
18 | starDefault = "starDefault",
19 | },
20 | sibling = {
21 | siblingDefault = "siblingDefault",
22 | },
23 | },
24 | doubleStarTest = {
25 | ["**"] = {
26 | doubleStarDefault = "doubleStarDefault",
27 | },
28 | sibling = {
29 | siblingDefault = "siblingDefault",
30 | },
31 | },
32 | },
33 | }
34 |
35 | local db = LibStub("AceDB-3.0"):New("MyDB", defaults)
36 | assert(db.profile.singleEntry == "singleEntry")
37 | assert(db.profile.tableEntry.tableDefault == "tableDefault")
38 | assert(db.profile.starTest.randomkey.starDefault == "starDefault")
39 | assert(db.profile.starTest.sibling.siblingDefault == "siblingDefault")
40 | assert(db.profile.starTest.sibling.starDefault == nil)
41 | assert(db.profile.doubleStarTest.randomkey.doubleStarDefault == "doubleStarDefault")
42 | assert(db.profile.doubleStarTest.sibling.siblingDefault == "siblingDefault")
43 | assert(db.profile.doubleStarTest.sibling.doubleStarDefault == "doubleStarDefault")
44 | end
45 |
46 | -- Test the dynamic creation of sections
47 | do
48 | local defaults = {
49 | char = { alpha = "alpha",},
50 | realm = { beta = "beta",},
51 | class = { gamma = "gamma",},
52 | race = { delta = "delta",},
53 | faction = { epsilon = "epsilon",},
54 | factionrealm = { zeta = "zeta",},
55 | profile = { eta = "eta",},
56 | global = { theta = "theta",},
57 | }
58 |
59 | local db = LibStub("AceDB-3.0"):New({}, defaults)
60 |
61 | assert(rawget(db, "char") == nil)
62 | assert(rawget(db, "realm") == nil)
63 | assert(rawget(db, "class") == nil)
64 | assert(rawget(db, "race") == nil)
65 | assert(rawget(db, "faction") == nil)
66 | assert(rawget(db, "factionrealm") == nil)
67 | assert(rawget(db, "profile") == nil)
68 | assert(rawget(db, "global") == nil)
69 | assert(rawget(db, "profiles") == nil)
70 |
71 | -- Check dynamic default creation
72 | assert(db.char.alpha == "alpha")
73 | assert(db.realm.beta == "beta")
74 | assert(db.class.gamma == "gamma")
75 | assert(db.race.delta == "delta")
76 | assert(db.faction.epsilon == "epsilon")
77 | assert(db.factionrealm.zeta == "zeta")
78 | assert(db.profile.eta == "eta")
79 | assert(db.global.theta == "theta")
80 | end
81 |
82 | -- Test OnProfileChanged
83 | do
84 | local testdb = LibStub("AceDB-3.0"):New({})
85 |
86 | local triggers = {}
87 |
88 | local function OnProfileChanged(message, db, ...)
89 | if message == "OnProfileChanged" and db == testdb then
90 | local profile = ...
91 | assert(profile == "Healers")
92 | triggers[message] = true
93 | end
94 | end
95 |
96 | testdb:RegisterCallback("OnProfileChanged", OnProfileChanged)
97 | testdb:SetProfile("Healers")
98 | assert(triggers.OnProfileChanged)
99 | end
100 |
101 | -- Test GetProfiles() fix for ACE-35
102 | do
103 | local db = LibStub("AceDB-3.0"):New({})
104 |
105 | local profiles = {
106 | "Healers",
107 | "Tanks",
108 | "Hunter",
109 | }
110 |
111 | for idx,profile in ipairs(profiles) do
112 | db:SetProfile(profile)
113 | end
114 |
115 | local profileList = db:GetProfiles()
116 | table.sort(profileList)
117 | assert(profileList[1] == "Healers")
118 | assert(profileList[2] == "Hunter")
119 | assert(profileList[3] == "Tanks")
120 | assert(profileList[4] == UnitName("player" .. " - " .. GetRealmName()))
121 | end
122 |
123 | -- Very simple default test
124 | do
125 | local defaults = {
126 | profile = {
127 | sub = {
128 | ["*"] = {
129 | sub2 = {},
130 | sub3 = {},
131 | },
132 | },
133 | },
134 | }
135 |
136 | local db = LibStub("AceDB-3.0"):New({}, defaults)
137 |
138 | assert(type(db.profile.sub.monkey.sub2) == "table")
139 | assert(type(db.profile.sub.apple.sub3) == "table")
140 |
141 | db.profile.sub.random.sub2.alpha = "alpha"
142 | end
143 |
144 | -- Table insert kills us
145 | do
146 | local defaults = {
147 | profile = {
148 | ["*"] = {},
149 | },
150 | }
151 |
152 | local db = LibStub("AceDB-3.0"):New({}, defaults)
153 |
154 | table.insert(db.profile.monkey, "alpha")
155 | table.insert(db.profile.random, "beta")
156 |
157 | -- Here, the tables db.profile.monkey should be REAL, not cached
158 | assert(rawget(db.profile, "monkey"))
159 | end
160 |
161 |
162 | -- Test multi-level defaults for hyper
163 | do
164 | local defaults = {
165 | profile = {
166 | autoSendRules = {
167 | ['*'] = {
168 | include = {
169 | ['*'] = {},
170 | },
171 | exclude = {
172 | ['*'] = {},
173 | },
174 | },
175 | },
176 | }
177 | }
178 |
179 | local db = LibStub("AceDB-3.0"):New({}, defaults)
180 |
181 | assert(rawget(db.profile.autoSendRules.Cairthas.include, "ptSets") == nil)
182 | assert(rawget(db.profile.autoSendRules.Cairthas.include, "items") == nil)
183 | table.insert(db.profile.autoSendRules.Cairthas.include.ptSets, "TradeSkill.Mat.ByProfession.Leatherworking")
184 | table.insert(db.profile.autoSendRules.Cairthas.include.items, "Light Leather")
185 |
186 | db.profile.autoSendRules.Cairthas.include.ptSets.boo = true
187 |
188 | -- Tables should be real now, not cached.
189 | assert(rawget(db.profile.autoSendRules.Cairthas.include, "ptSets"))
190 | assert(rawget(db.profile.autoSendRules.Cairthas.include, "items"))
191 | end
192 |
193 | do
194 | local testdb = LibStub("AceDB-3.0"):New("testdbtable", {profile = { test = 2, test3 = { a=1}}})
195 | assert(testdb.profile.test == 2) --true
196 | testdb.profile.test = 3
197 | testdb.profile.test2 = 4
198 | testdb.profile.test3.b = 2
199 | assert(testdb.profile.test == 3) --true
200 | assert(testdb.profile.test2 == 4) --true
201 | local firstprofile = testdb:GetCurrentProfile()
202 | testdb:SetProfile("newprofile")
203 | assert(testdb.profile.test == 2) --true
204 | testdb:CopyProfile(firstprofile)
205 | assert(testdb.profile.test == 3) --false, the value is 2
206 | assert(testdb.profile.test2 == 4) --true
207 | assert(testdb.profile.test3.a == 1)
208 | end
209 |
210 | do
211 | local testdb = LibStub("AceDB-3.0"):New({})
212 | testdb:SetProfile("testprofile")
213 | testdb:SetProfile("testprofile2")
214 | testdb:SetProfile("testprofile")
215 | assert(#testdb:GetProfiles() == 3)
216 | end
217 |
218 | do
219 |
220 | local TestDB = {
221 | ["namespaces"] = {
222 | ["Space"] = {
223 | ["profiles"] = {
224 | ["Default"] = {
225 | },
226 | },
227 | },
228 | },
229 | ["profiles"] = {
230 | ["Default"] = {
231 | ["notEmpty"] = true,
232 | },
233 | ["Test"] = {
234 | },
235 | },
236 | ["char"] = {
237 | ["TestChar - SomeRealm"] = {
238 | },
239 | },
240 | ["realm"] = {
241 | ["SomeRealm"] = {
242 | ["notEmpty"] = true,
243 | },
244 | },
245 | }
246 |
247 | local nsdef = {
248 | profile = {
249 | bla = true,
250 | }
251 | }
252 |
253 | wipe(LibStub("AceDB-3.0").db_registry)
254 | local testdb = LibStub("AceDB-3.0"):New(TestDB, nil, true)
255 | local ns = testdb:RegisterNamespace("Space", nsdef)
256 |
257 | WoWAPI_FireEvent("PLAYER_LOGOUT")
258 | assert(not TestDB.char)
259 | assert(TestDB.profiles.Test)
260 | assert(TestDB.realm.SomeRealm.notEmpty)
261 | assert(not TestDB.namespaces.Space.profiles)
262 | end
263 |
--------------------------------------------------------------------------------
/tests/AceComm-3.0.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("../LibStub/LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceComm-3.0/ChatThrottleLib.lua")
5 | dofile("../AceComm-3.0/AceComm-3.0.lua")
6 |
7 | switches = arg[1] or ""
8 |
9 | local VERBOSE,n = strfind(switches, "vv*") -- "v" anywhere in the first arg
10 | if VERBOSE then VERBOSE = n-VERBOSE+1 end -- "v"=1, "vv"=2, ...
11 |
12 |
13 |
14 |
15 | local AceComm = LibStub("AceComm-3.0")
16 |
17 | local function printf(format, ...)
18 | print(format:format(...))
19 | end
20 |
21 | assert(RegisterAddonMessagePrefix)
22 |
23 | -----------------------------------------------------------------------
24 | -----------------------------------------------------------------------
25 | -----------------------------------------------------------------------
26 | --
27 | -- Disable ChatThrottleLib?
28 | --
29 |
30 |
31 | local NOCTL = strfind(switches, "t")
32 |
33 | if NOCTL then -- "t" anywhere in the first arg
34 | print("NOTE: Testing mode without ChatThrottleLib!")
35 | -- Replace ChatThrottleLib with a dummy passthrough for testing purposes
36 | function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName)
37 | SendAddonMessage(prefix, text, chattype, target)
38 | end
39 | function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName)
40 | SendChatMessage(text, chattype, language, destination)
41 | end
42 | end
43 |
44 |
45 |
46 |
47 | -----------------------------------------------------------------------
48 | -----------------------------------------------------------------------
49 | -----------------------------------------------------------------------
50 | --
51 | -- Basic AceComm splitting/queueing tests
52 | --
53 |
54 | do
55 |
56 |
57 | local addon1 = {}
58 | local prefix1 = "Test"
59 |
60 | local addon2 = {}
61 | local prefix2 = "TestTest"
62 |
63 |
64 | local data = ""
65 | local received = {}
66 | local chartot = 0
67 |
68 | AceComm:Embed(addon1)
69 |
70 | local received1 = {}
71 | function addon1:OnCommReceived(prefix, message, distribution, sender)
72 | assert(self==addon1)
73 | assert(prefix == prefix1)
74 | assert(distribution == "RAID", dump(distribution))
75 | tinsert(received, message)
76 | tinsert(received1, message)
77 | assert(#message == #received1)
78 | assert(message == strsub(data,1,#message))
79 | chartot=chartot+#message
80 | end
81 |
82 | AceComm:Embed(addon2)
83 |
84 | local received2 = {}
85 | function addon2:OnCommReceived(prefix, message, distribution, sender)
86 | assert(self==addon2)
87 | assert(prefix == prefix2)
88 | assert(distribution == "GROUP", dump(distribution))
89 | tinsert(received, message)
90 | tinsert(received2, message)
91 | assert(#message == #received2+9)
92 | local control = string.char((#message-9)%32+1)
93 | assert(message == control.."OogaBoog"..strsub(data,1,#message-9))
94 | chartot=chartot+#message
95 | end
96 |
97 | addon1:RegisterComm(prefix1)
98 | addon2:RegisterComm(prefix2)
99 |
100 |
101 | local MSGS=255*4 -- length 1..1000, covers all of: Single, First+Last, First+Next+Last, First+Next+Next+Last
102 | data=string.char(math.random(10, 255))
103 | for i = 1,MSGS do
104 | data = data .. string.char(math.random(1, 255))
105 | end
106 |
107 |
108 |
109 | -- First send a boatload of data without pumping OnUpdates to CTL
110 |
111 | for i = 1,MSGS do
112 | if VERBOSE and VERBOSE>=2 then print("Sending len "..i) end
113 | addon1:SendCommMessage(prefix1, strsub(data,1,i), "RAID", nil)
114 | local control = string.char(i%32+1)
115 | addon2:SendCommMessage(prefix2, control.."OogaBoog"..strsub(data,1,i), "GROUP", nil)
116 | end
117 |
118 | -- Now start pumping OnUpdates; there should be plenty of stuff queued in CTL, and it should all be sent in the right order!
119 | if not NOCTL then
120 | local sampledmid
121 | local esttime = ( (MSGS+20)*MSGS*2/1.62 ) / ChatThrottleLib.MAX_CPS
122 | local midpos = esttime * 0.5
123 | local latepos = esttime * 0.9
124 |
125 | local lastchartot=0
126 | local dispinterval=20
127 |
128 | local t=0
129 | if VERBOSE then
130 | print("time","rcvtot","rcv1","rcv2","cps","CTL choke")
131 | end
132 | while #received < MSGS*2 do
133 | WoWAPI_FireUpdate(t)
134 | if t%dispinterval==0 then
135 | local cps = floor((chartot-lastchartot)/dispinterval)
136 | if VERBOSE then print(t..": ",#received, #received1, #received2, cps, ChatThrottleLib.bChoking) end
137 | lastchartot=chartot
138 | if t>midpos then -- when our bandwidth isn't mostly eaten by headers and stuff
139 | assert(cps>=ChatThrottleLib.MAX_CPS*0.6 and cpsmidpos and not sampledmid then
143 | sampledmid=true
144 | assert(#received > MSGS*1.33 and #received < MSGS*1.5, dump(#received, MSGS*1.33, MSGS*1.5)) -- would be around 1 if we sent the same amount of data in each message, but we send less around the start
145 | end
146 | if t>midpos and t= #received1*0.975 and #received2 < #received1*0.999, #received1.." : "..#received2)
149 | end
150 | t=t+1
151 | end
152 |
153 | assert(t>=esttime*0.9 and t<=esttime*1.1, dump(t, esttime))
154 |
155 | assert(sampledmid)
156 |
157 | end
158 |
159 | assert(#received==MSGS*2)
160 | assert(#received1==MSGS and #received2==MSGS)
161 |
162 | function addon1:OnCommReceived()
163 | assert(false,"We shouldn't receive more here now!!!!")
164 | end
165 |
166 | function addon2:OnCommReceived()
167 | assert(false,"We shouldn't receive more here now!!!!")
168 | end
169 |
170 | addon1:UnregisterComm(prefix1)
171 | addon2:UnregisterAllComm()
172 |
173 | end
174 |
175 |
176 | AceComm:SendCommMessage("Test", "This should not be received", "RAID", nil)
177 | AceComm:SendCommMessage("TestTest", "This should not be received", "GROUP", nil)
178 |
179 | WoWAPI_FireUpdate(GetTime()+100)
180 |
181 |
182 | -----------------------------------------------------------------------
183 | -----------------------------------------------------------------------
184 | -----------------------------------------------------------------------
185 | --
186 | -- Unit test escaping
187 | --
188 |
189 | local addon = AceComm:Embed({})
190 | local comms = {}
191 | function addon:OnCommReceived(...)
192 | tinsert(comms, {...})
193 | -- print("OnCommReceived", ...)
194 | end
195 | addon:RegisterComm("MyPrefix")
196 |
197 | local frame = CreateFrame("Frame")
198 | local events = {}
199 | frame:SetScript("OnEvent", function(self,event,...)
200 | tinsert(events, {...})
201 | -- print("CHAT_MSG_ADDON", ...)
202 | end)
203 | frame:RegisterEvent("CHAT_MSG_ADDON")
204 |
205 | for i=1,9 do
206 | local control = string.char(i)
207 | AceComm:SendCommMessage("MyPrefix", control.."asdf", "RAID")
208 | WoWAPI_FireUpdate(GetTime()+100)
209 |
210 | assert(#comms==i)
211 | assert(comms[i][1]=="MyPrefix")
212 | assert(comms[i][2]==control.."asdf")
213 | assert(comms[i][3]=="RAID")
214 | assert(comms[i][4]=="Sender")
215 |
216 | assert(#events==i)
217 | assert(events[i][1]=="MyPrefix")
218 | assert(events[i][2]=="\004"..control.."asdf")
219 | assert(events[i][3]=="RAID")
220 | assert(events[i][4]=="Sender")
221 | end
222 |
223 | -----------------------------------------------------------------------
224 | print "OK"
225 |
--------------------------------------------------------------------------------
/tests/wow_api.lua:
--------------------------------------------------------------------------------
1 | local _G = getfenv(0)
2 |
3 | local donothing = function() end
4 |
5 | local frames = {} -- Stores globally created frames, and their internal properties.
6 |
7 | local FrameClass = {} -- A class for creating frames.
8 | FrameClass.methods = { "SetScript", "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents", "Show", "Hide", "IsShown", "ClearAllPoints", "SetParent" }
9 | function FrameClass:New()
10 | local frame = {}
11 | for i,method in ipairs(self.methods) do
12 | frame[method] = self[method]
13 | end
14 | local frameProps = {
15 | events = {},
16 | scripts = {},
17 | timer = GetTime(),
18 | isShow = true,
19 | parent = nil,
20 | }
21 | return frame, frameProps
22 | end
23 | function FrameClass:SetScript(script,handler)
24 | frames[self].scripts[script] = handler
25 | end
26 | function FrameClass:RegisterEvent(event)
27 | frames[self].events[event] = true
28 | end
29 | function FrameClass:UnregisterEvent(event)
30 | frames[self].events[event] = nil
31 | end
32 | function FrameClass:UnregisterAllEvents(frame)
33 | for event in pairs(frames[self].events) do
34 | frames[self].events[event] = nil
35 | end
36 | end
37 | function FrameClass:Show()
38 | frames[self].isShow = true
39 | end
40 | function FrameClass:Hide()
41 | frames[self].isShow = false
42 | end
43 | function FrameClass:IsShown()
44 | return frames[self].isShow
45 | end
46 | function FrameClass:ClearAllPoints()
47 | end
48 | function FrameClass:SetParent(parent)
49 | frames[self].parent = parent
50 | end
51 |
52 |
53 | function CreateFrame(kind, name, parent)
54 | local frame,internal = FrameClass:New()
55 | internal.parent = parent
56 | frames[frame] = internal
57 | if name then
58 | _G[name] = frame
59 | end
60 | return frame
61 | end
62 |
63 | function UnitName(unit)
64 | return unit
65 | end
66 |
67 | function GetRealmName()
68 | return "Realm Name"
69 | end
70 |
71 | function UnitClass(unit)
72 | return "Warrior", "WARRIOR"
73 | end
74 |
75 | function UnitHealthMax()
76 | return 100
77 | end
78 |
79 | function UnitHealth()
80 | return 50
81 | end
82 |
83 | function GetNumRaidMembers()
84 | return 1
85 | end
86 |
87 | function GetNumPartyMembers()
88 | return 1
89 | end
90 |
91 | FACTION_HORDE = "Horde"
92 | FACTION_ALLIANCE = "Alliance"
93 |
94 | function UnitFactionGroup(unit)
95 | return "Horde", "Horde"
96 | end
97 |
98 | function UnitRace(unit)
99 | return "Undead", "Scourge"
100 | end
101 |
102 |
103 | _time = 0
104 | function GetTime()
105 | return _time
106 | end
107 |
108 | function IsAddOnLoaded() return nil end
109 |
110 | SlashCmdList = {}
111 |
112 | function __WOW_Input(text)
113 | local a,b = string.find(text, "^/%w+")
114 | local arg, text = string.sub(text, a,b), string.sub(text, b + 2)
115 | for k,handler in pairs(SlashCmdList) do
116 | local i = 0
117 | while true do
118 | i = i + 1
119 | if not _G["SLASH_" .. k .. i] then
120 | break
121 | elseif _G["SLASH_" .. k .. i] == arg then
122 | handler(text)
123 | return
124 | end
125 | end
126 | end;
127 | print("No command found:", text)
128 | end
129 |
130 | local ChatFrameTemplate = {
131 | AddMessage = function(self, text)
132 | print((string.gsub(text, "|c%x%x%x%x%x%x%x%x(.-)|r", "%1")))
133 | end
134 | }
135 |
136 | for i=1,7 do
137 | local f = {}
138 | for k,v in pairs(ChatFrameTemplate) do
139 | f[k] = v
140 | end
141 | _G["ChatFrame"..i] = f
142 | end
143 | DEFAULT_CHAT_FRAME = ChatFrame1
144 |
145 | debugstack = debug.traceback
146 | date = os.date
147 |
148 | function GetLocale()
149 | return "enUS"
150 | end
151 |
152 | function GetAddOnInfo()
153 | return
154 | end
155 |
156 | function GetNumAddOns()
157 | return 0
158 | end
159 |
160 | function getglobal(k)
161 | return _G[k]
162 | end
163 |
164 | function setglobal(k, v)
165 | _G[k] = v
166 | end
167 |
168 | local function _errorhandler(msg)
169 | print("--------- geterrorhandler error -------\n"..msg.."\n-----end error-----\n")
170 | end
171 |
172 | function geterrorhandler()
173 | return _errorhandler
174 | end
175 |
176 | function InCombatLockdown()
177 | return false
178 | end
179 |
180 | function IsLoggedIn()
181 | return false
182 | end
183 |
184 | function GetFramerate()
185 | return 60
186 | end
187 |
188 | function GetCVar(var)
189 | return "test"
190 | end
191 |
192 | time = os.clock
193 |
194 | strmatch = string.match
195 |
196 | function SendChatMessage(text, chattype, language, destination)
197 | assert(#text<255)
198 | WoWAPI_FireEvent("CHAT_MSG_"..strupper(chattype), text, "Sender", language or "Common")
199 | end
200 |
201 | local registeredPrefixes = {}
202 | function RegisterAddonMessagePrefix(prefix)
203 | assert(#prefix<=16) -- tested, 16 works /mikk, 20110327
204 | registeredPrefixes[prefix] = true
205 | end
206 |
207 | function SendAddonMessage(prefix, message, distribution, target)
208 | if RegisterAddonMessagePrefix then --4.1+
209 | assert(#message <= 255,
210 | string.format("SendAddonMessage: message too long (%d bytes > 255)",
211 | #message))
212 | -- CHAT_MSG_ADDON(prefix, message, distribution, sender)
213 | WoWAPI_FireEvent("CHAT_MSG_ADDON", prefix, message, distribution, "Sender")
214 | else -- allow RegisterAddonMessagePrefix to be nilled out to emulate pre-4.1
215 | assert(#prefix + #message < 255,
216 | string.format("SendAddonMessage: message too long (%d bytes)",
217 | #prefix + #message))
218 | -- CHAT_MSG_ADDON(prefix, message, distribution, sender)
219 | WoWAPI_FireEvent("CHAT_MSG_ADDON", prefix, message, distribution, "Sender")
220 | end
221 | end
222 |
223 | if not wipe then
224 | function wipe(tbl)
225 | for k in pairs(tbl) do
226 | tbl[k]=nil
227 | end
228 | end
229 | end
230 |
231 | function hooksecurefunc(func_name, post_hook_func)
232 | local orig_func = _G[func_name]
233 | assert(type(orig_func)=="function")
234 |
235 | _G[func_name] = function (...)
236 | local ret = { orig_func(...) } -- yeahyeah wasteful, see if i care, it's a test framework
237 | post_hook_func(...)
238 | return unpack(ret)
239 | end
240 | end
241 |
242 | RED_FONT_COLOR_CODE = ""
243 | GREEN_FONT_COLOR_CODE = ""
244 |
245 | StaticPopupDialogs = {}
246 |
247 | function WoWAPI_FireEvent(event,...)
248 | for frame, props in pairs(frames) do
249 | if props.events[event] then
250 | if props.scripts["OnEvent"] then
251 | for i=1,select('#',...) do
252 | _G["arg"..i] = select(i,...)
253 | end
254 | _G.event=event
255 | props.scripts["OnEvent"](frame,event,...)
256 | end
257 | end
258 | end
259 | end
260 |
261 | function WoWAPI_FireUpdate(forceNow)
262 | if forceNow then
263 | _time = forceNow
264 | end
265 | local now = GetTime()
266 | for frame,props in pairs(frames) do
267 | if props.isShow and props.scripts.OnUpdate then
268 | if now == 0 then
269 | props.timer = 0 -- reset back in case we reset the clock for more testing
270 | end
271 | _G.arg1=now-props.timer
272 | props.scripts.OnUpdate(frame,now-props.timer)
273 | props.timer = now
274 | end
275 | end
276 | end
277 |
278 |
279 |
280 |
281 | -- utility function for "dumping" a number of arguments (return a string representation of them)
282 | function dump(...)
283 | local t = {}
284 | for i=1,select("#", ...) do
285 | local v = select(i, ...)
286 | if type(v)=="string" then
287 | tinsert(t, string.format("%q", v))
288 | elseif type(v)=="table" then
289 | tinsert(t, tostring(v).." #"..#v)
290 | else
291 | tinsert(t, tostring(v))
292 | end
293 | end
294 | return "<"..table.concat(t, "> <")..">"
295 | end
296 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ColorPicker Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "ColorPicker", 28
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | -- Unfortunately we have no way to realistically detect if a client uses inverted alpha
15 | -- as no API will tell you. Wrath uses the old colorpicker, era uses the new one, both are inverted
16 | local INVERTED_ALPHA = (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE)
17 |
18 | --[[-----------------------------------------------------------------------------
19 | Support functions
20 | -------------------------------------------------------------------------------]]
21 | local function ColorCallback(self, r, g, b, a, isAlpha)
22 | if INVERTED_ALPHA and a then
23 | a = 1 - a
24 | end
25 | if not self.HasAlpha then
26 | a = 1
27 | end
28 | -- no change, skip update
29 | if r == self.r and g == self.g and b == self.b and a == self.a then
30 | return
31 | end
32 | self:SetColor(r, g, b, a)
33 | if ColorPickerFrame:IsVisible() then
34 | --colorpicker is still open
35 | self:Fire("OnValueChanged", r, g, b, a)
36 | else
37 | --colorpicker is closed, color callback is first, ignore it,
38 | --alpha callback is the final call after it closes so confirm now
39 | if isAlpha then
40 | self:Fire("OnValueConfirmed", r, g, b, a)
41 | end
42 | end
43 | end
44 |
45 | --[[-----------------------------------------------------------------------------
46 | Scripts
47 | -------------------------------------------------------------------------------]]
48 | local function Control_OnEnter(frame)
49 | frame.obj:Fire("OnEnter")
50 | end
51 |
52 | local function Control_OnLeave(frame)
53 | frame.obj:Fire("OnLeave")
54 | end
55 |
56 | local function ColorSwatch_OnClick(frame)
57 | ColorPickerFrame:Hide()
58 | local self = frame.obj
59 | if not self.disabled then
60 | ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
61 | ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
62 | ColorPickerFrame:SetClampedToScreen(true)
63 |
64 | if ColorPickerFrame.SetupColorPickerAndShow then -- 10.2.5 color picker overhaul
65 | local r2, g2, b2, a2 = self.r, self.g, self.b, (self.a or 1)
66 | if INVERTED_ALPHA then
67 | a2 = 1 - a2
68 | end
69 |
70 | local info = {
71 | swatchFunc = function()
72 | local r, g, b = ColorPickerFrame:GetColorRGB()
73 | local a = ColorPickerFrame:GetColorAlpha()
74 | ColorCallback(self, r, g, b, a)
75 | end,
76 |
77 | hasOpacity = self.HasAlpha,
78 | opacityFunc = function()
79 | local r, g, b = ColorPickerFrame:GetColorRGB()
80 | local a = ColorPickerFrame:GetColorAlpha()
81 | ColorCallback(self, r, g, b, a, true)
82 | end,
83 | opacity = a2,
84 |
85 | cancelFunc = function()
86 | ColorCallback(self, r2, g2, b2, a2, true)
87 | end,
88 |
89 | r = r2,
90 | g = g2,
91 | b = b2,
92 | }
93 |
94 | ColorPickerFrame:SetupColorPickerAndShow(info)
95 | else
96 | ColorPickerFrame.func = function()
97 | local r, g, b = ColorPickerFrame:GetColorRGB()
98 | local a = OpacitySliderFrame:GetValue()
99 | ColorCallback(self, r, g, b, a)
100 | end
101 |
102 | ColorPickerFrame.hasOpacity = self.HasAlpha
103 | ColorPickerFrame.opacityFunc = function()
104 | local r, g, b = ColorPickerFrame:GetColorRGB()
105 | local a = OpacitySliderFrame:GetValue()
106 | ColorCallback(self, r, g, b, a, true)
107 | end
108 |
109 | local r, g, b, a = self.r, self.g, self.b, 1 - (self.a or 1)
110 | if self.HasAlpha then
111 | ColorPickerFrame.opacity = a
112 | end
113 | ColorPickerFrame:SetColorRGB(r, g, b)
114 |
115 | ColorPickerFrame.cancelFunc = function()
116 | ColorCallback(self, r, g, b, a, true)
117 | end
118 |
119 | ColorPickerFrame:Show()
120 | end
121 | end
122 | AceGUI:ClearFocus()
123 | end
124 |
125 | --[[-----------------------------------------------------------------------------
126 | Methods
127 | -------------------------------------------------------------------------------]]
128 | local methods = {
129 | ["OnAcquire"] = function(self)
130 | self:SetHeight(24)
131 | self:SetWidth(200)
132 | self:SetHasAlpha(false)
133 | self:SetColor(0, 0, 0, 1)
134 | self:SetDisabled(nil)
135 | self:SetLabel(nil)
136 | end,
137 |
138 | -- ["OnRelease"] = nil,
139 |
140 | ["SetLabel"] = function(self, text)
141 | self.text:SetText(text)
142 | end,
143 |
144 | ["SetColor"] = function(self, r, g, b, a)
145 | self.r = r
146 | self.g = g
147 | self.b = b
148 | self.a = a or 1
149 | self.colorSwatch:SetVertexColor(r, g, b, a)
150 | end,
151 |
152 | ["SetHasAlpha"] = function(self, HasAlpha)
153 | self.HasAlpha = HasAlpha
154 | end,
155 |
156 | ["SetDisabled"] = function(self, disabled)
157 | self.disabled = disabled
158 | if self.disabled then
159 | self.frame:Disable()
160 | self.text:SetTextColor(0.5, 0.5, 0.5)
161 | else
162 | self.frame:Enable()
163 | self.text:SetTextColor(1, 1, 1)
164 | end
165 | end
166 | }
167 |
168 | --[[-----------------------------------------------------------------------------
169 | Constructor
170 | -------------------------------------------------------------------------------]]
171 | local function Constructor()
172 | local frame = CreateFrame("Button", nil, UIParent)
173 | frame:Hide()
174 |
175 | frame:EnableMouse(true)
176 | frame:SetScript("OnEnter", Control_OnEnter)
177 | frame:SetScript("OnLeave", Control_OnLeave)
178 | frame:SetScript("OnClick", ColorSwatch_OnClick)
179 |
180 | local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
181 | colorSwatch:SetWidth(19)
182 | colorSwatch:SetHeight(19)
183 | colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch
184 | colorSwatch:SetPoint("LEFT")
185 |
186 | local texture = frame:CreateTexture(nil, "BACKGROUND")
187 | colorSwatch.background = texture
188 | texture:SetWidth(16)
189 | texture:SetHeight(16)
190 | texture:SetColorTexture(1, 1, 1)
191 | texture:SetPoint("CENTER", colorSwatch)
192 | texture:Show()
193 |
194 | local checkers = frame:CreateTexture(nil, "BACKGROUND")
195 | colorSwatch.checkers = checkers
196 | checkers:SetWidth(14)
197 | checkers:SetHeight(14)
198 | checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers
199 | checkers:SetTexCoord(.25, 0, 0.5, .25)
200 | checkers:SetDesaturated(true)
201 | checkers:SetVertexColor(1, 1, 1, 0.75)
202 | checkers:SetPoint("CENTER", colorSwatch)
203 | checkers:Show()
204 |
205 | local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
206 | text:SetHeight(24)
207 | text:SetJustifyH("LEFT")
208 | text:SetTextColor(1, 1, 1)
209 | text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
210 | text:SetPoint("RIGHT")
211 |
212 | --local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
213 | --highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight
214 | --highlight:SetBlendMode("ADD")
215 | --highlight:SetAllPoints(frame)
216 |
217 | local widget = {
218 | colorSwatch = colorSwatch,
219 | text = text,
220 | frame = frame,
221 | type = Type
222 | }
223 | for method, func in pairs(methods) do
224 | widget[method] = func
225 | end
226 |
227 | return AceGUI:RegisterAsWidget(widget)
228 | end
229 |
230 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
231 |
--------------------------------------------------------------------------------
/tests/AceEvent-3.0.lua:
--------------------------------------------------------------------------------
1 | dofile("wow_api.lua")
2 | dofile("LibStub.lua")
3 | dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
4 | dofile("../AceEvent-3.0/AceEvent-3.0.lua")
5 |
6 | local AceEvent = LibStub("AceEvent-3.0")
7 |
8 | local addon = {}
9 |
10 | AceEvent:Embed(addon)
11 |
12 | -- Test embedding and then registering and unregistering and seeing that things are caught and NOT caught correctly
13 | do
14 | local eventResult
15 | function addon:EVENT_TEST(event,arg1)
16 | assert(self==addon)
17 | assert(event=="EVENT_TEST")
18 | eventResult = arg1
19 | end
20 |
21 | eventResult = 1
22 | addon:RegisterEvent("EVENT_TEST") -- simple reg & test
23 | WoWAPI_FireEvent("EVENT_TEST", 2)
24 | assert(eventResult==2)
25 |
26 | eventResult = 3
27 | addon:UnregisterEvent("SOMETHINGELSE") -- unreg something that doesn't exist
28 | WoWAPI_FireEvent("SOMETHINGELSE", 4) -- fire something with no handler
29 | assert(eventResult==3)
30 |
31 | eventResult = 5
32 | addon:UnregisterEvent("SOMETHINGELSE") -- again unregister something that doesn't exist (why? ohwell)
33 | WoWAPI_FireEvent("EVENT_TEST", 6) -- this should still fire
34 | assert(eventResult==6)
35 |
36 | eventResult = 7
37 | addon:UnregisterAllEvents() -- test unregging everything
38 | WoWAPI_FireEvent("EVENT_TEST", 8) -- this should NOT fire
39 | assert(eventResult==7)
40 |
41 | addon:RegisterEvent("EVENT_TEST") -- re-register
42 | WoWAPI_FireEvent("EVENT_TEST", 9)
43 | assert(eventResult==9) -- should fire again!
44 |
45 | local switched=0
46 | function addon:EVENT_TEST() -- overwrite handler, should work with self["methodname"] syntax
47 | switched=switched+1
48 | end
49 | WoWAPI_FireEvent("EVENT_TEST", 10)
50 | assert(switched==1)
51 | assert(eventResult==9)
52 |
53 | local woot=0
54 | addon:RegisterEvent("EVENT_TEST", function(event, arg)
55 | assert(event=="EVENT_TEST")
56 | assert(arg=="woot", dump(event,arg))
57 | woot=woot+1
58 | end) -- CHANGE registration (to a funcref even!)
59 | WoWAPI_FireEvent("EVENT_TEST", "woot")
60 | assert(switched==1)
61 | assert(eventResult==9)
62 | assert(woot==1)
63 |
64 | addon:UnregisterAllEvents()
65 | WoWAPI_FireEvent("EVENT_TEST")
66 | assert(switched==1)
67 | assert(eventResult==9)
68 | assert(woot==1)
69 | end
70 |
71 |
72 | -- Test nonembedded funcref calling style, two events to same handler
73 | do
74 | local eventName
75 | local eventCount=0
76 | local function handler(event, ...)
77 | eventName=event
78 | eventCount=eventCount+1
79 | end
80 |
81 | AceEvent:RegisterEvent("EVENT1", handler)
82 | AceEvent:RegisterEvent("EVENT2", handler)
83 |
84 | WoWAPI_FireEvent("EVENT1")
85 | assert(eventName=="EVENT1" and eventCount==1)
86 |
87 | WoWAPI_FireEvent("EVENT2")
88 | assert(eventName=="EVENT2" and eventCount==2)
89 |
90 | end
91 |
92 | -- Test "addonID" instead of self
93 | do
94 | local eventName
95 | local eventCount=0
96 | local function handler(event, ...)
97 | eventName=event
98 | eventCount=eventCount+1
99 | end
100 |
101 | local event3Count=0
102 | local function handler3(event, ...)
103 | event3Count=event3Count+1
104 | end
105 |
106 |
107 | AceEvent.RegisterEvent("myAddon", "EVENT1", handler)
108 | AceEvent.RegisterEvent("myOtherAddon", "EVENT2", handler)
109 | AceEvent.RegisterEvent("myOtherAddon", "EVENT3", handler3)
110 |
111 | WoWAPI_FireEvent("EVENT1")
112 | assert(eventName=="EVENT1" and eventCount==1)
113 |
114 | WoWAPI_FireEvent("EVENT2")
115 | assert(eventName=="EVENT2" and eventCount==2)
116 |
117 | WoWAPI_FireEvent("EVENT3")
118 | assert(event3Count==1)
119 |
120 | AceEvent.UnregisterAllEvents("myAddon") -- note "." calling style
121 |
122 | WoWAPI_FireEvent("EVENT1") -- should not fire
123 | assert(eventCount==2)
124 |
125 | WoWAPI_FireEvent("EVENT2")
126 | assert(eventCount==3)
127 |
128 | WoWAPI_FireEvent("EVENT3")
129 | assert(event3Count==2)
130 |
131 | AceEvent:UnregisterAllEvents("myOtherAddon") -- now ":" calling style
132 |
133 | WoWAPI_FireEvent("EVENT1") -- should not fire
134 | assert(eventCount==3)
135 |
136 | WoWAPI_FireEvent("EVENT2") -- should not fire
137 | assert(eventCount==3)
138 |
139 | WoWAPI_FireEvent("EVENT3") -- should not fire
140 | assert(event3Count==2)
141 |
142 | end
143 |
144 |
145 |
146 |
147 |
148 | -- Test multiple args, different types
149 | do
150 | local arg3={}
151 |
152 | local args
153 | local function handler(event, ...)
154 | args = { ... }
155 | end
156 |
157 | AceEvent:RegisterEvent("ARGZZ", handler) -- ":" calling style, self=AceEvent
158 |
159 | WoWAPI_FireEvent("ARGZZ", "arg1", 2, arg3)
160 |
161 | assert(#args==3)
162 | assert(args[1]=="arg1")
163 | assert(args[2]==2)
164 | assert(args[3]==arg3)
165 | end
166 |
167 |
168 | -- Test user-supplied args, all styles
169 | do
170 | local addon={}
171 | local n=0
172 | AceEvent:Embed(addon)
173 |
174 | -- test self["methodname"]
175 | function addon:HANDLER(userarg, event, a1,a2)
176 | assert(self==addon)
177 | assert(userarg=="userarg")
178 | assert(event=="EVENT")
179 | assert(a1==1 and a2==2, dump(a1,a2))
180 | n=n+1
181 | end
182 | addon:RegisterEvent("EVENT", "HANDLER", "userarg")
183 | WoWAPI_FireEvent("EVENT",1,2)
184 | assert(n==1)
185 |
186 | -- test functionref
187 | local function handler(userarg, event, a1,a2)
188 | assert(userarg==nil)
189 | assert(event=="EVENT")
190 | assert(a1==1 and a2==2, dump(a1,a2))
191 | n=n+1
192 | end
193 | addon:RegisterEvent("EVENT", handler, nil) -- look, a nil that should still be passed!
194 | WoWAPI_FireEvent("EVENT",1,2)
195 | assert(n==2)
196 |
197 | -- test functionref with self="addonId"
198 | AceEvent.RegisterEvent("myAddon", "EVENT", handler, nil) -- look, a nil that should still be passed!
199 | WoWAPI_FireEvent("EVENT",1,2)
200 | assert(n==4) -- should have fired twice, once for the addon table, once for "myAddon"
201 |
202 | addon:UnregisterAllEvents("myAddon") -- unregs BOTH for addon and "myAddon"
203 | WoWAPI_FireEvent("EVENT",1,2)
204 | assert(n==4) -- shouldnt have fired
205 |
206 | end
207 |
208 |
209 | -- Register a methodname on AceEvent itself -- should error
210 | do
211 | local addon={}
212 | local ok,res = pcall(AceEvent.RegisterEvent, AceEvent, "whatever")
213 | assert(not ok and res=="Usage: RegisterEvent(\"eventname\", \"methodname\"): do not use Library:RegisterEvent(), use your own 'self'", dump(ok,res))
214 | end
215 |
216 | -- Register a nonexistant methodname -- should error
217 | do
218 | local addon={}
219 | local ok,res = pcall(AceEvent.RegisterEvent, addon, "THISDOESNTEXIST")
220 | assert(not ok and res=="Usage: RegisterEvent(\"eventname\", \"methodname\"): 'methodname' - method 'THISDOESNTEXIST' not found on self.", dump(ok,res))
221 | end
222 |
223 | -- Don't give UnregAll an arg -- should error
224 | do
225 | local ok,res = pcall(AceEvent.UnregisterAllEvents)
226 | assert(not ok and res==[[Usage: UnregisterAllEvents([whatFor]): missing 'self' or "addonId" to unregister events for.]], dump(ok,res))
227 | end
228 |
229 | -- Attempt to unregister everything on the library itself -- should error
230 | do
231 | local ok,res = pcall(AceEvent.UnregisterAllEvents, AceEvent)
232 | assert(not ok and res==[[Usage: UnregisterAllEvents([whatFor]): supply a meaningful 'self' or "addonId"]], dump(ok,res))
233 | end
234 |
235 | -- These should be ok though (note '.' rather than ':' )
236 | AceEvent.UnregisterAllEvents(AceEvent, "BLAH")
237 | AceEvent.UnregisterAllEvents("BLAH")
238 | AceEvent.UnregisterAllEvents("BLAH", AceEvent)
239 | AceEvent.UnregisterAllEvents({})
240 |
241 |
242 |
243 |
244 |
245 |
246 | do -- Tests on messages.
247 | local messageResult
248 | function addon:MESSAGE_TEST(message,...)
249 | end
250 | -- TODO
251 | end
252 |
253 |
254 |
255 | ------------------------------------------------
256 | print "OK"
257 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ScrollFrame Container
3 | Plain container that scrolls its content and doesn't grow in height.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "ScrollFrame", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs, assert, type = pairs, assert, type
11 | local min, max, floor = math.min, math.max, math.floor
12 |
13 | -- WoW APIs
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Support functions
18 | -------------------------------------------------------------------------------]]
19 | local function FixScrollOnUpdate(frame)
20 | frame:SetScript("OnUpdate", nil)
21 | frame.obj:FixScroll()
22 | end
23 |
24 | --[[-----------------------------------------------------------------------------
25 | Scripts
26 | -------------------------------------------------------------------------------]]
27 | local function ScrollFrame_OnMouseWheel(frame, value)
28 | frame.obj:MoveScroll(value)
29 | end
30 |
31 | local function ScrollFrame_OnSizeChanged(frame)
32 | frame:SetScript("OnUpdate", FixScrollOnUpdate)
33 | end
34 |
35 | local function ScrollBar_OnScrollValueChanged(frame, value)
36 | frame.obj:SetScroll(value)
37 | end
38 |
39 | --[[-----------------------------------------------------------------------------
40 | Methods
41 | -------------------------------------------------------------------------------]]
42 | local methods = {
43 | ["OnAcquire"] = function(self)
44 | self:SetScroll(0)
45 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
46 | end,
47 |
48 | ["OnRelease"] = function(self)
49 | self.status = nil
50 | for k in pairs(self.localstatus) do
51 | self.localstatus[k] = nil
52 | end
53 | self.scrollframe:SetPoint("BOTTOMRIGHT")
54 | self.scrollbar:Hide()
55 | self.scrollBarShown = nil
56 | self.content.height, self.content.width, self.content.original_width = nil, nil, nil
57 | end,
58 |
59 | ["SetScroll"] = function(self, value)
60 | local status = self.status or self.localstatus
61 | local viewheight = self.scrollframe:GetHeight()
62 | local height = self.content:GetHeight()
63 | local offset
64 |
65 | if viewheight > height then
66 | offset = 0
67 | else
68 | offset = floor((height - viewheight) / 1000.0 * value)
69 | end
70 | self.content:ClearAllPoints()
71 | self.content:SetPoint("TOPLEFT", 0, offset)
72 | self.content:SetPoint("TOPRIGHT", 0, offset)
73 | status.offset = offset
74 | status.scrollvalue = value
75 | end,
76 |
77 | ["MoveScroll"] = function(self, value)
78 | local status = self.status or self.localstatus
79 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
80 |
81 | if self.scrollBarShown then
82 | local diff = height - viewheight
83 | local delta = 1
84 | if value < 0 then
85 | delta = -1
86 | end
87 | self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
88 | end
89 | end,
90 |
91 | ["FixScroll"] = function(self)
92 | if self.updateLock then return end
93 | self.updateLock = true
94 | local status = self.status or self.localstatus
95 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
96 | local offset = status.offset or 0
97 | -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
98 | -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
99 | if viewheight < height + 2 then
100 | if self.scrollBarShown then
101 | self.scrollBarShown = nil
102 | self.scrollbar:Hide()
103 | self.scrollbar:SetValue(0)
104 | self.scrollframe:SetPoint("BOTTOMRIGHT")
105 | if self.content.original_width then
106 | self.content.width = self.content.original_width
107 | end
108 | self:DoLayout()
109 | end
110 | else
111 | if not self.scrollBarShown then
112 | self.scrollBarShown = true
113 | self.scrollbar:Show()
114 | self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
115 | if self.content.original_width then
116 | self.content.width = self.content.original_width - 20
117 | end
118 | self:DoLayout()
119 | end
120 | local value = (offset / (viewheight - height) * 1000)
121 | if value > 1000 then value = 1000 end
122 | self.scrollbar:SetValue(value)
123 | self:SetScroll(value)
124 | if value < 1000 then
125 | self.content:ClearAllPoints()
126 | self.content:SetPoint("TOPLEFT", 0, offset)
127 | self.content:SetPoint("TOPRIGHT", 0, offset)
128 | status.offset = offset
129 | end
130 | end
131 | self.updateLock = nil
132 | end,
133 |
134 | ["LayoutFinished"] = function(self, width, height)
135 | self.content:SetHeight(height or 0 + 20)
136 |
137 | -- update the scrollframe
138 | self:FixScroll()
139 |
140 | -- schedule another update when everything has "settled"
141 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
142 | end,
143 |
144 | ["SetStatusTable"] = function(self, status)
145 | assert(type(status) == "table")
146 | self.status = status
147 | if not status.scrollvalue then
148 | status.scrollvalue = 0
149 | end
150 | end,
151 |
152 | ["OnWidthSet"] = function(self, width)
153 | local content = self.content
154 | content.width = width - (self.scrollBarShown and 20 or 0)
155 | content.original_width = width
156 | end,
157 |
158 | ["OnHeightSet"] = function(self, height)
159 | local content = self.content
160 | content.height = height
161 | end
162 | }
163 | --[[-----------------------------------------------------------------------------
164 | Constructor
165 | -------------------------------------------------------------------------------]]
166 | local function Constructor()
167 | local frame = CreateFrame("Frame", nil, UIParent)
168 | local num = AceGUI:GetNextWidgetNum(Type)
169 |
170 | local scrollframe = CreateFrame("ScrollFrame", nil, frame)
171 | scrollframe:SetPoint("TOPLEFT")
172 | scrollframe:SetPoint("BOTTOMRIGHT")
173 | scrollframe:EnableMouseWheel(true)
174 | scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
175 | scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
176 |
177 | local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
178 | scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
179 | scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
180 | scrollbar:SetMinMaxValues(0, 1000)
181 | scrollbar:SetValueStep(1)
182 | scrollbar:SetValue(0)
183 | scrollbar:SetWidth(16)
184 | scrollbar:Hide()
185 | -- set the script as the last step, so it doesn't fire yet
186 | scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
187 |
188 | local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
189 | scrollbg:SetAllPoints(scrollbar)
190 | scrollbg:SetColorTexture(0, 0, 0, 0.4)
191 |
192 | --Container Support
193 | local content = CreateFrame("Frame", nil, scrollframe)
194 | content:SetPoint("TOPLEFT")
195 | content:SetPoint("TOPRIGHT")
196 | content:SetHeight(400)
197 | scrollframe:SetScrollChild(content)
198 |
199 | local widget = {
200 | localstatus = { scrollvalue = 0 },
201 | scrollframe = scrollframe,
202 | scrollbar = scrollbar,
203 | content = content,
204 | frame = frame,
205 | type = Type
206 | }
207 | for method, func in pairs(methods) do
208 | widget[method] = func
209 | end
210 | scrollframe.obj, scrollbar.obj = widget, widget
211 |
212 | return AceGUI:RegisterAsContainer(widget)
213 | end
214 |
215 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
216 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Keybinding Widget
3 | Set Keybindings in the Config UI.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Keybinding", 27
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 |
20 | local function Control_OnEnter(frame)
21 | frame.obj:Fire("OnEnter")
22 | end
23 |
24 | local function Control_OnLeave(frame)
25 | frame.obj:Fire("OnLeave")
26 | end
27 |
28 | local function Keybinding_OnClick(frame, button)
29 | if button == "LeftButton" or button == "RightButton" then
30 | local self = frame.obj
31 | if self.waitingForKey then
32 | frame:EnableKeyboard(false)
33 | frame:EnableMouseWheel(false)
34 | frame:EnableGamePadButton(false)
35 | self.msgframe:Hide()
36 | frame:UnlockHighlight()
37 | self.waitingForKey = nil
38 | else
39 | frame:EnableKeyboard(true)
40 | frame:EnableMouseWheel(true)
41 | frame:EnableGamePadButton(true)
42 | self.msgframe:Show()
43 | frame:LockHighlight()
44 | self.waitingForKey = true
45 | end
46 | end
47 | AceGUI:ClearFocus()
48 | end
49 |
50 | local ignoreKeys = {
51 | ["BUTTON1"] = true, ["BUTTON2"] = true,
52 | ["UNKNOWN"] = true,
53 | ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
54 | ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
55 | }
56 | local function Keybinding_OnKeyDown(frame, key)
57 | local self = frame.obj
58 | if self.waitingForKey then
59 | local keyPressed = key
60 | if keyPressed == "ESCAPE" then
61 | keyPressed = ""
62 | else
63 | if ignoreKeys[keyPressed] then return end
64 | if IsShiftKeyDown() then
65 | keyPressed = "SHIFT-"..keyPressed
66 | end
67 | if IsControlKeyDown() then
68 | keyPressed = "CTRL-"..keyPressed
69 | end
70 | if IsAltKeyDown() then
71 | keyPressed = "ALT-"..keyPressed
72 | end
73 | end
74 |
75 | frame:EnableKeyboard(false)
76 | frame:EnableMouseWheel(false)
77 | frame:EnableGamePadButton(false)
78 | self.msgframe:Hide()
79 | frame:UnlockHighlight()
80 | self.waitingForKey = nil
81 |
82 | if not self.disabled then
83 | self:SetKey(keyPressed)
84 | self:Fire("OnKeyChanged", keyPressed)
85 | end
86 | end
87 | end
88 |
89 | local function Keybinding_OnMouseDown(frame, button)
90 | if button == "LeftButton" or button == "RightButton" then
91 | return
92 | elseif button == "MiddleButton" then
93 | button = "BUTTON3"
94 | elseif button == "Button4" then
95 | button = "BUTTON4"
96 | elseif button == "Button5" then
97 | button = "BUTTON5"
98 | end
99 | Keybinding_OnKeyDown(frame, button)
100 | end
101 |
102 | local function Keybinding_OnMouseWheel(frame, direction)
103 | local button
104 | if direction >= 0 then
105 | button = "MOUSEWHEELUP"
106 | else
107 | button = "MOUSEWHEELDOWN"
108 | end
109 | Keybinding_OnKeyDown(frame, button)
110 | end
111 |
112 | --[[-----------------------------------------------------------------------------
113 | Methods
114 | -------------------------------------------------------------------------------]]
115 | local methods = {
116 | ["OnAcquire"] = function(self)
117 | self:SetWidth(200)
118 | self:SetLabel("")
119 | self:SetKey("")
120 | self.waitingForKey = nil
121 | self.msgframe:Hide()
122 | self:SetDisabled(false)
123 | self.button:EnableKeyboard(false)
124 | self.button:EnableMouseWheel(false)
125 | self.button:EnableGamePadButton(false)
126 | end,
127 |
128 | -- ["OnRelease"] = nil,
129 |
130 | ["SetDisabled"] = function(self, disabled)
131 | self.disabled = disabled
132 | if disabled then
133 | self.button:Disable()
134 | self.label:SetTextColor(0.5,0.5,0.5)
135 | else
136 | self.button:Enable()
137 | self.label:SetTextColor(1,1,1)
138 | end
139 | end,
140 |
141 | ["SetKey"] = function(self, key)
142 | if (key or "") == "" then
143 | self.button:SetText(NOT_BOUND)
144 | self.button:SetNormalFontObject("GameFontNormal")
145 | else
146 | self.button:SetText(key)
147 | self.button:SetNormalFontObject("GameFontHighlight")
148 | end
149 | end,
150 |
151 | ["GetKey"] = function(self)
152 | local key = self.button:GetText()
153 | if key == NOT_BOUND then
154 | key = nil
155 | end
156 | return key
157 | end,
158 |
159 | ["SetLabel"] = function(self, label)
160 | self.label:SetText(label or "")
161 | if (label or "") == "" then
162 | self.alignoffset = nil
163 | self:SetHeight(24)
164 | else
165 | self.alignoffset = 30
166 | self:SetHeight(44)
167 | end
168 | end,
169 | }
170 |
171 | --[[-----------------------------------------------------------------------------
172 | Constructor
173 | -------------------------------------------------------------------------------]]
174 |
175 | local ControlBackdrop = {
176 | bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
177 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
178 | tile = true, tileSize = 16, edgeSize = 16,
179 | insets = { left = 3, right = 3, top = 3, bottom = 3 }
180 | }
181 |
182 | local function keybindingMsgFixWidth(frame)
183 | frame:SetWidth(frame.msg:GetWidth() + 10)
184 | frame:SetScript("OnUpdate", nil)
185 | end
186 |
187 | local function Constructor()
188 | local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
189 |
190 | local frame = CreateFrame("Frame", nil, UIParent)
191 | local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
192 |
193 | button:EnableMouse(true)
194 | button:EnableMouseWheel(false)
195 | button:RegisterForClicks("AnyDown")
196 | button:SetScript("OnEnter", Control_OnEnter)
197 | button:SetScript("OnLeave", Control_OnLeave)
198 | button:SetScript("OnClick", Keybinding_OnClick)
199 | button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
200 | button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
201 | button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
202 | button:SetScript("OnGamePadButtonDown", Keybinding_OnKeyDown)
203 | button:SetPoint("BOTTOMLEFT")
204 | button:SetPoint("BOTTOMRIGHT")
205 | button:SetHeight(24)
206 | button:EnableKeyboard(false)
207 | button:EnableGamePadButton(false)
208 |
209 | local text = button:GetFontString()
210 | text:SetPoint("LEFT", 7, 0)
211 | text:SetPoint("RIGHT", -7, 0)
212 |
213 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
214 | label:SetPoint("TOPLEFT")
215 | label:SetPoint("TOPRIGHT")
216 | label:SetJustifyH("CENTER")
217 | label:SetHeight(18)
218 |
219 | local msgframe = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
220 | msgframe:SetHeight(30)
221 | msgframe:SetBackdrop(ControlBackdrop)
222 | msgframe:SetBackdropColor(0,0,0)
223 | msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
224 | msgframe:SetFrameLevel(1000)
225 | msgframe:SetToplevel(true)
226 |
227 | local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
228 | msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
229 | msgframe.msg = msg
230 | msg:SetPoint("TOPLEFT", 5, -5)
231 | msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
232 | msgframe:SetPoint("BOTTOM", button, "TOP")
233 | msgframe:Hide()
234 |
235 | local widget = {
236 | button = button,
237 | label = label,
238 | msgframe = msgframe,
239 | frame = frame,
240 | alignoffset = 30,
241 | type = Type
242 | }
243 | for method, func in pairs(methods) do
244 | widget[method] = func
245 | end
246 | button.obj = widget
247 |
248 | return AceGUI:RegisterAsWidget(widget)
249 | end
250 |
251 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
252 |
--------------------------------------------------------------------------------
/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | EditBox Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "EditBox", 29
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local tostring, pairs = tostring, pairs
10 |
11 | -- WoW APIs
12 | local PlaySound = PlaySound
13 | local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 | local _G = _G
16 |
17 | --[[-----------------------------------------------------------------------------
18 | Support functions
19 | -------------------------------------------------------------------------------]]
20 | if not AceGUIEditBoxInsertLink then
21 | -- upgradeable hook
22 | if ChatFrameUtil and ChatFrameUtil.InsertLink then
23 | hooksecurefunc(ChatFrameUtil, "InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
24 | elseif ChatEdit_InsertLink then
25 | hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
26 | end
27 | end
28 |
29 | function _G.AceGUIEditBoxInsertLink(text)
30 | for i = 1, AceGUI:GetWidgetCount(Type) do
31 | local editbox = _G["AceGUI-3.0EditBox"..i]
32 | if editbox and editbox:IsVisible() and editbox:HasFocus() then
33 | editbox:Insert(text)
34 | return true
35 | end
36 | end
37 | end
38 |
39 | local function ShowButton(self)
40 | if not self.disablebutton then
41 | self.button:Show()
42 | self.editbox:SetTextInsets(0, 20, 3, 3)
43 | end
44 | end
45 |
46 | local function HideButton(self)
47 | self.button:Hide()
48 | self.editbox:SetTextInsets(0, 0, 3, 3)
49 | end
50 |
51 | --[[-----------------------------------------------------------------------------
52 | Scripts
53 | -------------------------------------------------------------------------------]]
54 | local function Control_OnEnter(frame)
55 | frame.obj:Fire("OnEnter")
56 | end
57 |
58 | local function Control_OnLeave(frame)
59 | frame.obj:Fire("OnLeave")
60 | end
61 |
62 | local function Frame_OnShowFocus(frame)
63 | frame.obj.editbox:SetFocus()
64 | frame:SetScript("OnShow", nil)
65 | end
66 |
67 | local function EditBox_OnEscapePressed(frame)
68 | AceGUI:ClearFocus()
69 | end
70 |
71 | local function EditBox_OnEnterPressed(frame)
72 | local self = frame.obj
73 | local value = frame:GetText()
74 | local cancel = self:Fire("OnEnterPressed", value)
75 | if not cancel then
76 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
77 | HideButton(self)
78 | end
79 | end
80 |
81 | local function EditBox_OnReceiveDrag(frame)
82 | local self = frame.obj
83 | local type, id, info, extra = GetCursorInfo()
84 | local name
85 | if type == "item" then
86 | name = info
87 | elseif type == "spell" then
88 | if C_Spell and C_Spell.GetSpellName then
89 | name = C_Spell.GetSpellName(extra)
90 | else
91 | name = GetSpellInfo(id, info)
92 | end
93 | elseif type == "macro" then
94 | name = GetMacroInfo(id)
95 | end
96 | if name then
97 | self:SetText(name)
98 | self:Fire("OnEnterPressed", name)
99 | ClearCursor()
100 | HideButton(self)
101 | AceGUI:ClearFocus()
102 | end
103 | end
104 |
105 | local function EditBox_OnTextChanged(frame)
106 | local self = frame.obj
107 | local value = frame:GetText()
108 | if tostring(value) ~= tostring(self.lasttext) then
109 | self:Fire("OnTextChanged", value)
110 | self.lasttext = value
111 | ShowButton(self)
112 | end
113 | end
114 |
115 | local function EditBox_OnFocusGained(frame)
116 | AceGUI:SetFocus(frame.obj)
117 | end
118 |
119 | local function Button_OnClick(frame)
120 | local editbox = frame.obj.editbox
121 | editbox:ClearFocus()
122 | EditBox_OnEnterPressed(editbox)
123 | end
124 |
125 | --[[-----------------------------------------------------------------------------
126 | Methods
127 | -------------------------------------------------------------------------------]]
128 | local methods = {
129 | ["OnAcquire"] = function(self)
130 | -- height is controlled by SetLabel
131 | self:SetWidth(200)
132 | self:SetDisabled(false)
133 | self:SetLabel()
134 | self:SetText()
135 | self:DisableButton(false)
136 | self:SetMaxLetters(0)
137 | end,
138 |
139 | ["OnRelease"] = function(self)
140 | self:ClearFocus()
141 | end,
142 |
143 | ["SetDisabled"] = function(self, disabled)
144 | self.disabled = disabled
145 | if disabled then
146 | self.editbox:EnableMouse(false)
147 | self.editbox:ClearFocus()
148 | self.editbox:SetTextColor(0.5,0.5,0.5)
149 | self.label:SetTextColor(0.5,0.5,0.5)
150 | else
151 | self.editbox:EnableMouse(true)
152 | self.editbox:SetTextColor(1,1,1)
153 | self.label:SetTextColor(1,.82,0)
154 | end
155 | end,
156 |
157 | ["SetText"] = function(self, text)
158 | self.lasttext = text or ""
159 | self.editbox:SetText(text or "")
160 | self.editbox:SetCursorPosition(0)
161 | HideButton(self)
162 | end,
163 |
164 | ["GetText"] = function(self, text)
165 | return self.editbox:GetText()
166 | end,
167 |
168 | ["SetLabel"] = function(self, text)
169 | if text and text ~= "" then
170 | self.label:SetText(text)
171 | self.label:Show()
172 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
173 | self:SetHeight(44)
174 | self.alignoffset = 30
175 | else
176 | self.label:SetText("")
177 | self.label:Hide()
178 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
179 | self:SetHeight(26)
180 | self.alignoffset = 12
181 | end
182 | end,
183 |
184 | ["DisableButton"] = function(self, disabled)
185 | self.disablebutton = disabled
186 | if disabled then
187 | HideButton(self)
188 | end
189 | end,
190 |
191 | ["SetMaxLetters"] = function (self, num)
192 | self.editbox:SetMaxLetters(num or 0)
193 | end,
194 |
195 | ["ClearFocus"] = function(self)
196 | self.editbox:ClearFocus()
197 | self.frame:SetScript("OnShow", nil)
198 | end,
199 |
200 | ["SetFocus"] = function(self)
201 | self.editbox:SetFocus()
202 | if not self.frame:IsShown() then
203 | self.frame:SetScript("OnShow", Frame_OnShowFocus)
204 | end
205 | end,
206 |
207 | ["HighlightText"] = function(self, from, to)
208 | self.editbox:HighlightText(from, to)
209 | end
210 | }
211 |
212 | --[[-----------------------------------------------------------------------------
213 | Constructor
214 | -------------------------------------------------------------------------------]]
215 | local function Constructor()
216 | local num = AceGUI:GetNextWidgetNum(Type)
217 | local frame = CreateFrame("Frame", nil, UIParent)
218 | frame:Hide()
219 |
220 | local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
221 | editbox:SetAutoFocus(false)
222 | editbox:SetFontObject(ChatFontNormal)
223 | editbox:SetScript("OnEnter", Control_OnEnter)
224 | editbox:SetScript("OnLeave", Control_OnLeave)
225 | editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
226 | editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
227 | editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
228 | editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
229 | editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
230 | editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
231 | editbox:SetTextInsets(0, 0, 3, 3)
232 | editbox:SetMaxLetters(256)
233 | editbox:SetPoint("BOTTOMLEFT", 6, 0)
234 | editbox:SetPoint("BOTTOMRIGHT")
235 | editbox:SetHeight(19)
236 |
237 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
238 | label:SetPoint("TOPLEFT", 0, -2)
239 | label:SetPoint("TOPRIGHT", 0, -2)
240 | label:SetJustifyH("LEFT")
241 | label:SetHeight(18)
242 |
243 | local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
244 | button:SetWidth(40)
245 | button:SetHeight(20)
246 | button:SetPoint("RIGHT", -2, 0)
247 | button:SetText(OKAY)
248 | button:SetScript("OnClick", Button_OnClick)
249 | button:Hide()
250 |
251 | local widget = {
252 | alignoffset = 30,
253 | editbox = editbox,
254 | label = label,
255 | button = button,
256 | frame = frame,
257 | type = Type
258 | }
259 | for method, func in pairs(methods) do
260 | widget[method] = func
261 | end
262 | editbox.obj, button.obj = widget, widget
263 |
264 | return AceGUI:RegisterAsWidget(widget)
265 | end
266 |
267 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
268 |
--------------------------------------------------------------------------------