diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml
deleted file mode 100644
index 2f93975..0000000
--- a/.gitea/workflows/release.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: release
-
-on:
- push:
- tags:
- - '*-coa.*' # Asc-1.1.6-coa.2, 9.1.40-coa.3, etc.
- - 'v*' # v0.3.0 for repos without an upstream version
-
-jobs:
- release:
- runs-on: linux-amd64
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # build_zip uses git archive HEAD; full history is fine
-
- - name: Build per-addon zip(s)
- run: bash tools/build_zip.sh
-
- - name: Publish release (Gitea API direct; no action dependency)
- env:
- GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- REPO: ${{ github.repository }}
- TAG: ${{ github.ref_name }}
- API: ${{ github.server_url }}/api/v1
- # Gitea attachment ceiling is 200 MiB (see roles/gitea config).
- # Skip anything larger so one oversized asset doesn't fail the job.
- MAX_BYTES: 209715200
- run: |
- set -euo pipefail
- # Create the release (or reuse if it already exists for this tag).
- RID=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
- "$API/repos/$REPO/releases/tags/$TAG" 2>/dev/null \
- | jq -r '.id // empty')
- if [ -z "$RID" ]; then
- RID=$(curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \
- -H "Content-Type: application/json" \
- "$API/repos/$REPO/releases" \
- -d "$(jq -nc --arg t "$TAG" '{tag_name:$t,name:$t,draft:false,prerelease:false,hide_archive_links:true}')" \
- | jq -r '.id')
- fi
- echo "release id: $RID"
- # Gitea honors hide_archive_links only on edit, not create — PATCH it
- # so the auto-generated Source Code (zip/tar.gz) links stay hidden.
- curl -sf -X PATCH -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \
- "$API/repos/$REPO/releases/$RID" -d '{"hide_archive_links":true}' >/dev/null || true
- # Upload every dist/*.zip. Per-asset failures don't fail the job —
- # we want partial releases to still publish rather than block the
- # whole pipeline on one big file.
- failed=0
- uploaded=0
- for f in dist/*.zip; do
- name=$(basename "$f")
- size=$(stat -c '%s' "$f")
- if [ "$size" -gt "$MAX_BYTES" ]; then
- echo "::warning::skip $name (${size} B > ${MAX_BYTES} B Gitea limit; host on CDN instead)"
- failed=$((failed+1))
- continue
- fi
- echo "uploading $name ($(numfmt --to=iec "$size"))"
- if curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \
- -F "attachment=@$f" \
- "$API/repos/$REPO/releases/$RID/assets?name=$name" \
- | jq -r '" -> " + .browser_download_url'; then
- uploaded=$((uploaded+1))
- else
- echo "::warning::upload failed for $name"
- failed=$((failed+1))
- fi
- done
- echo "release published: $uploaded uploaded, $failed skipped/failed"
- # Only fail the job if NO assets uploaded — a release with zero
- # attachments isn't useful to anyone.
- [ "$uploaded" -gt 0 ]
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..cb7b432
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,77 @@
+name: "Bug Report"
+description: Create a report to help us improve this addon
+labels: '🐛 Bug'
+body:
+- type: markdown
+ attributes:
+ value: |
+ Please search for existing issues before creating a new one.
+
+- type: textarea
+ attributes:
+ label: Description
+ description: What did you expect to happen and what happened instead?
+ validations:
+ required: true
+
+- type: dropdown
+ id: flavor
+ attributes:
+ label: Realm
+ description: What realm did this occur on?
+ options:
+ - Area 52 (Default)
+ - Seasonal
+ - Grizzly Hills
+ - Rexxar
+ - Other
+ validations:
+ required: true
+
+- type: checkboxes
+ id: testing
+ attributes:
+ label: Tested with only this addon
+ description: Did you try having just this addon as the only enabled addon and everything else disabled?
+ options:
+ - label: "Yes"
+ - label: "No"
+ validations:
+ required: true
+
+- type: textarea
+ attributes:
+ label: Lua Error
+ description: |
+ Do you have an error log of what happened? If you don't see any errors, make sure that error reporting is enabled (`/console scriptErrors 1`)
+ validations:
+ required: false
+
+- type: textarea
+ attributes:
+ label: Reproduction Steps
+ description: Please list out the steps to reproduce your bug.
+ placeholder: |
+ 1. Go to '...'
+ 2. Click on '....'
+ 3. Scroll down to '....'
+ 4. See error
+ validations:
+ required: true
+
+- type: input
+ attributes:
+ label: Last Good Version
+ description: |
+ Was it working in a previous version? If yes, which update did it stop working? If you don't know, when was the last date you were aware it was working
+ placeholder: "MM/DD/YYYY"
+ validations:
+ required: false
+
+- type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to help explain your problem.
+ placeholder: Click here to attach your screenshots via the editor button in the top right.
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..ec4bb38
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..bbcbbe7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/PULL_REQUEST_TEPMLATE.md b/.github/PULL_REQUEST_TEPMLATE.md
new file mode 100644
index 0000000..30d2afa
--- /dev/null
+++ b/.github/PULL_REQUEST_TEPMLATE.md
@@ -0,0 +1,28 @@
+# Description
+
+Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
+
+Fixes #(issue)
+
+## Type of change
+
+Please delete options that are not relevant.
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+
+## How Has This Been Tested
+
+Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
+
+- [ ] Test A
+- [ ] Test B
+
+## Checklist
+
+
+- [ ] I have performed a self-review of my own code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+
+
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ec92999..44356e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,4 @@
.install
.lua/*
.vscode
-.idea
-dist/
+.idea
\ No newline at end of file
diff --git a/Decursive/DCR_init.lua b/Decursive/DCR_init.lua
index b97c825..efaaeb2 100644
--- a/Decursive/DCR_init.lua
+++ b/Decursive/DCR_init.lua
@@ -124,8 +124,8 @@ DC.AfflictionSound = "Interface\\AddOns\\Decursive\\Sounds\\AfflictionAlert.wav"
--DC.AfflictionSound = "Sound\\Doodad\\BellTollTribal.wav"
DC.FailedSound = "Interface\\AddOns\\Decursive\\Sounds\\FailedSpell.wav";
-DC.IconON = "Interface\\AddOns\\Decursive\\iconON.blp";
-DC.IconOFF = "Interface\\AddOns\\Decursive\\iconOFF.blp";
+DC.IconON = "Interface\\AddOns\\Decursive\\iconON.tga";
+DC.IconOFF = "Interface\\AddOns\\Decursive\\iconOFF.tga";
for class in pairs(RAID_CLASS_COLORS) do
DC["CLASS_"..class] = class
@@ -142,7 +142,6 @@ DC.POISON = 8;
DC.DISEASE = 16;
DC.CHARMED = 32;
DC.NOTYPE = 64;
-DC.BLEED = 128; -- CoA: synthetic dispel type (UnitAura returns "" for bleeds; we re-tag by spellId via DC.BleedSpellIDs)
DC.NORMAL = 8;
@@ -315,7 +314,6 @@ function D:OnInitialize() -- Called on ADDON_LOADED -- {{{
[DC.POISON] = "Poison";
[DC.DISEASE] = "Disease";
[DC.CHARMED] = "Charm";
- [DC.BLEED] = "Bleed";
}
DC.NameToTypes = D:tReverse(DC.TypeNames);
@@ -328,7 +326,6 @@ function D:OnInitialize() -- Called on ADDON_LOADED -- {{{
[DC.POISON] = "22DD22";
[DC.DISEASE] = "995533";
[DC.CHARMED] = "FF0000";
- [DC.BLEED] = "AA1111"; -- darker red so it reads distinct from CHARMED
[DC.NOTYPE] = "AAAAAA";
}
@@ -502,24 +499,17 @@ function D:OnInitialize() -- Called on ADDON_LOADED -- {{{
}
elseif C_Player:IsCustomClass() then
-- CoA custom-class dispels (mapped to Decursive affliction types)
- DC.SpellsToUse[DS["COA_ROLL_BACK"]] = { Types = {DC.MAGIC, DC.CURSE, DC.DISEASE, DC.POISON}, IsBest = 0, Pet = false, } -- Chronomancer (Roll Back clears any harmful effect)
+ DC.SpellsToUse[DS["COA_CONTINUUM_RESTORATION"]] = { Types = {DC.MAGIC}, IsBest = 0, Pet = false, } -- Chronomancer
DC.SpellsToUse[DS["COA_DEVOUR_CURSE"]] = { Types = {DC.CURSE}, IsBest = 0, Pet = false, } -- Cultist
DC.SpellsToUse[DS["COA_REBUKE"]] = { Types = {DC.MAGIC, DC.DISEASE, DC.POISON}, IsBest = 1, Pet = false, } -- Templar
DC.SpellsToUse[DS["COA_ANTIVENOM"]] = { Types = {DC.POISON}, IsBest = 0, Pet = false, } -- Venomancer (baseline, poison-only — curse-dispel in DBC doesn't fire server-side)
- DC.SpellsToUse[DS["COA_BLIGHT_ANTIDOTE"]] = { Types = {DC.POISON}, IsBest = 1, Pet = false, } -- Venomancer (MoA — same Antidote/Antivenom pattern as 800905; the dedicated curse-cure 524824 is deliberately not registered: like Antivenom's DBC curse-dispel it is unverified to fire server-side)
+ DC.SpellsToUse[DS["COA_BLIGHT_ANTIDOTE"]] = { Types = {DC.POISON}, IsBest = 1, Pet = false, } -- Venomancer (MoA — same Antidote/Antivenom pattern as 800905; Venomancer curse-dispel needs the dedicated 524824 spell)
DC.SpellsToUse[DS["COA_BURN_IMPURITIES"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 0, Pet = false, } -- Pyromancer
DC.SpellsToUse[DS["COA_SURVIVAL_POTION"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 0, Pet = false, } -- Ranger
DC.SpellsToUse[DS["COA_HEMAL_EXCISION"]] = { Types = {DC.CURSE}, IsBest = 0, Pet = false, } -- Bloodmage
DC.SpellsToUse[DS["COA_WARDING_RUNE"]] = { Types = {DC.MAGIC}, IsBest = 0, Pet = false, } -- Runemaster
DC.SpellsToUse[DS["COA_PRAYER_OF_ELUNE"]] = { Types = {DC.MAGIC}, IsBest = 0, Pet = false, } -- Starcaller
DC.SpellsToUse[DS["COA_WITCHBLOOD_TONIC"]] = { Types = {DC.CURSE}, IsBest = 0, Pet = false, } -- Witch Hunter
- DC.SpellsToUse[DS["COA_SANCTIFY"]] = { Types = {DC.MAGIC, DC.DISEASE, DC.POISON}, IsBest = 1, Pet = false, } -- Sun Cleric
- DC.SpellsToUse[DS["COA_SOOTHING_TOUCH"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 1, Pet = false, } -- Primalist
- DC.SpellsToUse[DS["COA_SOOTHING_TOUCH_MOA"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 1, Pet = false, } -- Primalist MoA
- DC.SpellsToUse[DS["COA_CLEANSING_IDOL"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 0, Pet = false, } -- Witch Doctor — Cleansing Idol (AoE, can't direct-target via click)
- DC.SpellsToUse[DS["COA_HEXBREAK"]] = { Types = {DC.CURSE}, IsBest = 1, Pet = false, } -- Witch Doctor — Hexbreak (single-target curse removal, 40yd, instant; DBC type reads "Magic" but description+gameplay = Curse, cf. Soothing Touch)
- DC.SpellsToUse[DS["COA_NANOBOT_CLEANSER"]] = { Types = {DC.DISEASE, DC.POISON}, IsBest = 1, Pet = false, } -- Tinker — Nanobot Cleanser (single-target, direct-castable)
- DC.SpellsToUse[DS["COA_CAUTERIZE"]] = { Types = {DC.MAGIC, DC.POISON, DC.BLEED}, IsBest = 1, Pet = false, } -- Pyromancer — Cauterize (Magic + Poison via dummy; 1 Bleed via Dispel Mechanic, re-tagged by DC.BleedSpellIDs)
end
-- }}}
@@ -827,7 +817,7 @@ function D:OnDisable() -- When the addon is disabled by Ace
D.Status.Enabled = false;
D.DcrFullyInitialized = false;
- D:SetIcon("Interface\\AddOns\\Decursive\\iconOFF.blp");
+ D:SetIcon("Interface\\AddOns\\Decursive\\iconOFF.tga");
if ( D.profile.ShowDebuffsFrame) then
D.MFContainer:Hide();
@@ -987,7 +977,6 @@ function D:Configure() --{{{
CuringSpells[DC.POISON] = false;
CuringSpells[DC.DISEASE] = false;
CuringSpells[DC.CHARMED] = false;
- CuringSpells[DC.BLEED] = false; -- CoA: reset so Cauterize doesn't ghost after respec
local Spell, spellName, Type, _;
local GetSpellInfo = _G.GetSpellInfo;
@@ -1176,7 +1165,7 @@ function D:GetSpellsTranslations(FromDIAG)
-- GetSpellsTranslations catches any IDs that don't resolve.
if C_Player:IsCustomClass() then -- CoA
local customSpells = {
- ["COA_ROLL_BACK"] = { 804490, }, -- Chronomancer (all harmful)
+ ["COA_CONTINUUM_RESTORATION"] = { 804490, }, -- Chronomancer (Magic)
["COA_DEVOUR_CURSE"] = { 800402, }, -- Cultist (Curse)
["COA_REBUKE"] = { 525051, }, -- Templar/Monk (Magic, Disease, Poison)
["COA_ANTIVENOM"] = { 800905, }, -- Venomancer (Poison)
@@ -1187,14 +1176,6 @@ function D:GetSpellsTranslations(FromDIAG)
["COA_WARDING_RUNE"] = { 804232, }, -- Runemaster/SpiritMage (Magic)
["COA_PRAYER_OF_ELUNE"] = { 801987, }, -- Starcaller (Magic)
["COA_WITCHBLOOD_TONIC"] = { 802278, }, -- WitchHunter (Curse)
- ["COA_SANCTIFY"] = { 524968, }, -- Sun Cleric (Magic, Poison, Disease)
- ["COA_MENDING_TOUCH"] = { 524971, }, -- Primalist passive (Soothing Touch +Poison +Disease, Neutralizing Touch self-heal on Magic dispel) — intentionally translation-only, never registered in SpellsToUse (passive, not castable)
- ["COA_SOOTHING_TOUCH"] = { 801439, }, -- Primalist (Poison, Disease — DBC type "Magic" doesn't fire; trust gameplay)
- ["COA_SOOTHING_TOUCH_MOA"] = { 520841, }, -- Primalist MoA (Poison, Disease — same Soothing-Touch variant pattern as Venomancer's Antivenom/Blight pair)
- ["COA_CLEANSING_IDOL"] = { 504840, }, -- Witch Doctor (Disease, Poison — AoE idol, 30yd, ticks every 3s)
- ["COA_HEXBREAK"] = { 806240, }, -- Witch Doctor (Curse — single-target, 40yd, instant; DBC type "Magic" doesn't fire, trust description+gameplay)
- ["COA_NANOBOT_CLEANSER"] = { 502537, }, -- Tinker / Invention (Disease, Poison — single-target, 40yd, ticks every 3s for 15s)
- ["COA_CAUTERIZE"] = { 560749, }, -- Pyromancer (Magic + Poison via dummy script; 1 Bleed via Dispel Mechanic — DC.BLEED, re-tagged by DC.BleedSpellIDs)
}
for k,v in pairs(customSpells) do Spells[k] = v end
end
diff --git a/Decursive/Dcr_BleedIDs.lua b/Decursive/Dcr_BleedIDs.lua
deleted file mode 100644
index 33a0eaf..0000000
--- a/Decursive/Dcr_BleedIDs.lua
+++ /dev/null
@@ -1,116 +0,0 @@
--- Decursive — CoA bleed-aura spell IDs
--- Auto-generated from db.exil.es (coa-db) — DO NOT EDIT by hand.
--- Regenerate with:
--- SELECT s.id FROM spell s
--- WHERE EXISTS (SELECT 1 FROM jsonb_array_elements(s.effects) e
--- WHERE (e->>'id')::int = 6 -- SPELL_EFFECT_APPLY_AURA
--- AND (e->>'aura')::int = 3 -- SPELL_AURA_PERIODIC_DAMAGE
--- AND (e->>'mechanic')::int = 15) -- MECHANIC_BLEED
--- ORDER BY s.id;
--- Generated: 2026-05-27T18:37:37Z Count: 1491
-
-local DC = DcrC;
-
--- Packed as comma-separated IDs (~16/line) so regens diff cleanly.
--- Parsed once at addon load into a {[id]=true} hash for O(1) lookup.
-local packed = [[
-703,772,1079,1080,1081,1822,1823,1824,1826,1943,3147,4102,4244,6546,6547,6548
-8631,8632,8633,8639,8640,8818,9492,9493,9752,9894,9896,9904,10044,11273,11274,11275
-11289,11290,11572,11573,11574,11575,11977,12054,12721,13318,13443,13445,13738,14087,14118,14331
-14874,14903,15583,15976,16095,16393,16403,16406,16509,17153,17407,17504,18075,18078,18106,18200
-18202,19771,21948,21949,24192,24331,24332,25208,26839,26867,26884,27003,27008,27556,27638,28913
-29574,29578,29583,29906,29935,30285,30639,31041,31410,31956,32019,32901,33745,33865,33912,35144
-35318,35321,36023,36054,36332,36383,36590,36617,36965,36991,37123,37662,37973,38363,38772,38801
-38810,39198,39215,39382,40199,41092,41932,42395,42397,42658,43093,43153,43246,43931,43937,46845
-47465,48130,48261,48286,48374,48567,48568,48573,48574,48671,48672,48675,48676,48880,48920,49678
-49799,49800,50498,50729,51275,52401,52504,52771,52873,53317,53499,53578,53579,53580,53581,53582
-53602,54668,54703,54708,55102,55249,55276,55550,55604,55622,55645,57661,58459,58517,58830,58978
-59007,59239,59256,59262,59264,59268,59269,59343,59349,59444,59682,59691,59825,59826,59881,59882
-59883,59884,59885,59886,59989,61164,61896,62318,62331,62418,65033,66620,67679,70278,70279,71926
-75160,80183,80304,80629,80636,83532,85137,85138,85139,85242,85327,85339,85356,92365,92468,92716
-100332,100632,101478,102884,102887,102894,102900,156943,158045,164018,182200,201161,202026,202072,202884,202887
-202894,202900,234785,254002,254118,254120,254126,254138,254669,254671,254902,255434,255435,255436,255777,255922
-256416,257330,257342,257343,257344,257525,267018,267020,271853,272355,273872,273873,273874,273875,273876,273877
-273878,273879,273880,273881,273882,273883,273887,274279,274321,274322,274323,274324,274325,274326,274327,274328
-274329,274330,274331,274332,274870,274871,274872,275327,275662,275699,275700,275701,275702,275703,275704,276204
-276205,276206,276207,276208,276209,276210,276211,276212,276213,277532,282288,282289,282290,282291,282292,282293
-282294,282295,282296,282297,283003,283510,284564,284840,284845,284846,284847,284848,284881,284890,284892,285052
-285053,285054,285055,285056,285057,285058,285059,285060,285061,285062,285063,285071,285164,285165,285166,285167
-285168,285169,285170,285694,285897,285901,285902,285903,285904,285905,285906,285907,285908,285909,286035,286036
-286037,286038,286039,286040,286041,286181,286182,286183,286184,286185,286186,286187,286428,286429,286430,286431
-286432,286433,290242,290244,290245,290246,290247,290248,290249,290250,291026,291027,291028,291029,291030,291031
-291041,291056,300844,300870,300933,300934,300935,300936,300937,300938,300939,303010,303017,303046,304003,304167
-304223,312451,312525,312778,312786,312802,312842,312844,312970,313165,313292,313415,316451,316525,316778,316786
-316802,316842,316844,316970,317165,317292,317415,320451,320525,320778,320786,320802,320842,320844,320970,321165
-321292,321415,340015,340052,340095,340119,340516,350009,350010,350039,350052,350057,350069,350302,350346,350378
-350379,351014,351053,351092,351096,351121,351284,351285,351343,351344,351349,351350,351351,354043,354072,354073
-354274,354281,354292,354619,354620,354621,354643,354644,354645,354830,354835,354858,354859,354860,354864,354865
-354866,354976,354995,355247,355263,355375,355376,355437,355485,355500,355561,355764,384294,385396,391369,413006
-462136,500073,500127,500351,501640,501641,501642,501643,501644,501645,501646,501647,501648,501649,501650,501651
-501687,501688,501689,501690,501691,501692,501693,501694,501704,501705,501706,501707,502732,502733,503561,504291
-504669,504670,504671,504672,504673,504674,504675,504676,520610,520712,520713,520714,520715,520716,520781,524964
-560101,560102,560103,560104,560313,560356,560407,561303,572725,573337,575836,575837,600703,600772,601079,601822
-601943,633745,680279,680744,680766,704256,705023,705757,706808,707229,707303,782754,782801,783054,783055,783056
-800341,800772,800990,801023,802568,802569,802570,802571,802572,802573,802580,802587,803851,803859,803860,803861
-803862,803863,803864,804143,804600,805366,805832,806569,806576,806670,806671,806882,806883,806884,806885,806886
-806887,806898,806899,806900,806901,806902,806903,807237,807324,807325,807326,807327,807328,807329,807330,850518
-860210,901020,901021,901022,901023,901081,901149,901150,901151,901152,901153,901154,901185,901186,901187,901188
-901189,901190,901191,901192,904000,904001,904002,904003,904004,904005,904006,904007,904008,904009,904010,904020
-904021,904022,904023,904024,904025,904026,904027,904028,904029,904030,904040,904041,904042,904043,904044,904045
-904046,904047,904048,904049,904050,904060,904061,904062,904063,904064,904065,904066,904067,904068,904069,904070
-904080,904081,904082,904083,904084,904085,904086,904087,904088,904089,904090,904100,904101,904102,904103,904104
-904105,904106,904107,904108,904109,904110,904120,904121,904122,904123,904124,904125,904126,904127,904140,904141
-904142,904143,904144,904145,904146,904147,904160,904161,904162,904163,904164,904165,904166,904167,904180,904181
-904182,904183,904184,904185,904186,904187,904200,904201,904202,904203,904204,904205,904206,904207,904220,904221
-904222,904223,904224,904225,904226,904227,904960,904961,904962,904963,904964,904965,904966,904967,904968,904980
-904981,904982,904983,904984,904985,904986,904987,904988,907000,907001,907002,907003,907004,907005,907006,907007
-907008,907020,907021,907022,907023,907024,907025,907026,907027,907028,907040,907041,907042,907043,907044,907045
-907046,907047,907048,907060,907061,907062,907063,907064,907065,907066,907067,907068,947470,947471,947472,947473
-947474,947475,947476,947477,947478,947479,947480,947481,954809,954815,954883,954884,954885,954886,954887,954888
-954889,965150,965408,965630,965747,965758,965762,965772,966380,975040,978693,978694,978695,982251,982450,982682
-982683,982684,982685,982686,982687,982688,982703,982704,982705,982706,982707,983021,983022,983023,983024,983025
-983026,983027,983028,983029,983030,983031,983032,983037,983251,983260,983261,983262,983263,983264,983265,983266
-983267,983663,984698,984702,984818,984828,984831,984865,986011,986012,986013,986014,986015,986016,986017,986018
-986019,986020,987149,990240,992373,992716,992722,992768,992802,992833,992943,992991,993001,993096,993740,993741
-993742,993752,993900,997099,997243,997244,997245,997246,997247,997248,997249,997250,997251,997252,997316,997595
-997765,997766,997767,997768,997769,997770,997771,1100703,1100772,1100790,1100791,1100792,1100793,1100794,1100795,1101079
-1101822,1101823,1101824,1101943,1106546,1106547,1106548,1108631,1108632,1108633,1108639,1108640,1109007,1109492,1109493,1109752
-1109824,1109826,1109894,1109896,1109904,1111273,1111274,1111275,1111289,1111290,1111572,1111573,1111574,1112721,1114874,1114903
-1115583,1124331,1124332,1125208,1126839,1126867,1126884,1127003,1127007,1127008,1127556,1127638,1129583,1131041,1133745,1133746
-1133747,1136332,1137066,1143104,1146845,1147465,1148567,1148568,1148573,1148574,1148580,1148581,1148671,1148672,1148675,1148676
-1149799,1149800,1149804,1150498,1153578,1153579,1153580,1153581,1153582,1155550,1155622,1158978,1159881,1159882,1159883,1159884
-1159885,1159886,1161164,1163071,1163468,1180242,1180251,1180252,1180253,1180254,1180255,1402322,1407046,1407048,1569398,1570396
-1572620,1572621,1572622,1572623,1572624,1572625,1572626,1572627,1572628,1572629,1572630,1572631,1572638,1573293,1574215,1574241
-1574267,1575466,1575467,1575468,1575469,1575470,1575471,1575472,1576594,1576595,1576596,1576597,1576598,1576599,1576600,1576601
-1576602,1576603,1580246,1584827,1587588,1588276,1588281,1588282,1588283,1588284,1588346,1588348,1588372,1588841,1588842,1588843
-1588844,1588845,1588846,1588847,1588848,1588849,1588850,1588851,1588852,1588894,1590352,1590575,1590576,1590577,1590578,1590579
-1590580,1590581,1590582,1590583,1590584,1901020,1901021,1901022,1901023,1954815,2100021,2100022,2100023,2100024,2100170,2100752
-2100913,2102164,2102580,2102654,2102655,2102656,2102657,2102681,2102682,2102683,2102684,2102842,2102843,2102844,2102845,2106029
-2106030,2106031,2106032,2110917,2110918,2110919,2110920,2112408,2112409,2112410,2112411,2118240,2118241,2118242,2118243,2118326
-2118327,2118328,2118329,2122122,2122123,2122124,2122125,2122323,2122324,2122325,2122326,2125205,2125206,2125207,2125208,2125292
-2125293,2125294,2125295,2125372,2125373,2125374,2125375,2125601,2125602,2125603,2125604,2125664,2125665,2125666,2125667,2130032
-2130174,2130814,2130815,2130816,2130817,2130829,2130855,2130856,2130857,2135600,2135601,2135602,2135603,2135657,2135658,2135659
-2135660,2135668,2135669,2135670,2135671,2135747,2135748,2135749,2135750,2135819,2135820,2135821,2135822,2135824,2135825,2135826
-2135827,2135833,2135834,2135835,2135836,2135857,2135858,2135859,2135860,2135877,2135878,2135879,2135880,2136058,2136059,2136060
-2136061,2136326,2136327,2136328,2136329,2136382,2136383,2136384,2136385,2136398,2136399,2136400,2136401,2137739,2137740,2137741
-2137742,2137807,2137808,2137809,2137810,2141254,2141255,2141256,2141257,2141572,2141573,2141574,2141575,2142208,2142209,2142210
-2142211,2142516,2142517,2142518,2142519,2145205,2148844,2148845,2148846,2148847,2150775,2150776,2150777,2150778,2150844,2150845
-2150846,2150847,2151239,2151357,2151372,2151451,2151452,2151453,2151454,2152541,2152542,2152543,2152544,2152614,2152615,2152616
-2152617,2152775,2152776,2152777,2152778,2153067,2153239,2153357,2153372,2154541,2154542,2154543,2154544,2154614,2154615,2154616
-2154617,2154867,2156122,2156123,2156124,2156125,2156323,2156324,2156325,2156326,2251020,2251021,2251022,2251023,2304587,2304809
-2304815,2304883,2304884,2304885,2304886,2304887,2304888,2304889,3100021,3100022,3100023,3100024,3100170,3100752,3102164,3102580
-3102654,3102655,3102656,3102657,3102681,3102682,3102683,3102684,3106029,3106030,3106031,3106032,3123924,3123925,3123926,3123927
-3125205,3125206,3125207,3125208,3125292,3125293,3125294,3125295,3125372,3125373,3125374,3125375,3125601,3125602,3125603,3125604
-3125664,3125665,3125666,3125667,3130032,3130174,3130814,3130815,3130816,3130817,3135600,3135601,3135602,3135603,3135657,3135658
-3135659,3135660,3135668,3135669,3135670,3135671,3135747,3135748,3135749,3135750,3135819,3135820,3135821,3135822,3135824,3135825
-3135826,3135827,3135833,3135834,3135835,3135836,3135857,3135858,3135859,3135860,3135877,3135878,3135879,3135880,3136058,3136059
-3136060,3136061,3136326,3136327,3136328,3136329,3136382,3136383,3136384,3136385,3136398,3136399,3136400,3136401,3137739,3137740
-3137741,3137742,3137807,3137808,3137809,3137810,3141254,3141255,3141256,3141257,3141572,3141573,3141574,3141575,3142208,3142209
-3142210,3142211,3142516,3142517,3142518,3142519,3280243,3304815,3954809,4125431,5011037,5011166,5036870,5432530,8000004,9931133
-9980645,10013445,10092716
-]]
-
-DC.BleedSpellIDs = {}
-for id in string.gmatch(packed, "%d+") do
- DC.BleedSpellIDs[tonumber(id)] = true
-end
diff --git a/Decursive/Dcr_LiveList.xml b/Decursive/Dcr_LiveList.xml
index cdc890d..982cc0a 100644
--- a/Decursive/Dcr_LiveList.xml
+++ b/Decursive/Dcr_LiveList.xml
@@ -84,7 +84,7 @@
-
+
@@ -97,7 +97,7 @@
-
+
diff --git a/Decursive/Dcr_opt.lua b/Decursive/Dcr_opt.lua
index c8fcfb5..bb99850 100644
--- a/Decursive/Dcr_opt.lua
+++ b/Decursive/Dcr_opt.lua
@@ -79,7 +79,6 @@ function D:GetDefaultsSettings()
[DC.POISON] = 4,
[DC.DISEASE] = 5,
[DC.CHARMED] = 6,
- [DC.BLEED] = 7,
},
},
@@ -1600,17 +1599,6 @@ local function GetOptions()
disabled = function() return not D.Status.CuringSpells[DC.CHARMED] end,
order = 146
},
- CureBleed = {
- type = "toggle",
- name = " "..L["BLEED"],
- desc = L["OPT_BLEEDCHECK_DESC"],
- get = function() return D:GetCureCheckBoxStatus(DC.BLEED) end,
- set = function()
- D:SetCureOrder (DC.BLEED);
- end,
- disabled = function() return not D.Status.CuringSpells[DC.BLEED] end,
- order = 147
- },
}
}, -- }}}
@@ -1788,7 +1776,6 @@ local TypesToUName = {
[DC.POISON] = "POISON",
[DC.DISEASE] = "DISEASE",
[DC.CHARMED] = "CHARM",
- [DC.BLEED] = "BLEED",
}
local CureCheckBoxes = false;
@@ -1816,7 +1803,6 @@ function D:CheckCureOrder ()
[DC.POISON] = 4,
[DC.DISEASE] = 5,
[DC.CHARMED] = 6,
- [DC.BLEED] = 7,
};
local AuthorizedValues = {
[false] = true; -- LOL Yes, it's TRUE tnat FALSE is an authorized value xD
@@ -1833,8 +1819,6 @@ function D:CheckCureOrder ()
[-15] = DC.DISEASE,
[6] = DC.CHARMED,
[-16] = DC.CHARMED,
- [7] = DC.BLEED,
- [-17] = DC.BLEED,
};
local GivenValues = {};
@@ -1877,7 +1861,6 @@ function D:SetCureOrder (ToChange)
[DC.POISON] = D.options.args.CureOptions.args.CurePoison,
[DC.DISEASE] = D.options.args.CureOptions.args.CureDisease,
[DC.CHARMED] = D.options.args.CureOptions.args.CureCharmed,
- [DC.BLEED] = D.options.args.CureOptions.args.CureBleed, -- CoA: added with DC.BLEED
}
end
diff --git a/Decursive/Decursive.lua b/Decursive/Decursive.lua
index 34de0f6..98969f9 100644
--- a/Decursive/Decursive.lua
+++ b/Decursive/Decursive.lua
@@ -397,25 +397,19 @@ do
if D.LiveList.TestItemDisplayed and i == 1 and Unit ~= "target" and Unit ~= "mouseover" and UnitExists(Unit) then
D:Debug("|cFFFF0000Setting test debuff for %s (debuff %d)|r", Unit, i);
- return "Test item", DC.TypeNames[D.Status.ReversedCureOrder[1]], 2, "Interface\\AddOns\\Decursive\\iconON.blp", D.LiveList.TestItemDisplayed + 70;
+ return "Test item", DC.TypeNames[D.Status.ReversedCureOrder[1]], 2, "Interface\\AddOns\\Decursive\\iconON.tga", D.LiveList.TestItemDisplayed + 70;
end
--D:Debug("|cFFFF0000Getting debuffs for %s , id = %d|r", Unit, i);
- -- Name, rank, Texture, Applications, TypeName, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId = UnitAura("unit", index or ["name", "rank"][, "filter"])
+ -- Name, rank, Texture, Applications, TypeName, duration, expirationTime, unitCaster, isStealable = UnitAura("unit", index or ["name", "rank"][, "filter"])
- local Name, rank, Texture, Applications, TypeName, Duration, expirationTime, _src, _stealable, _consolidate, spellId = UnitAura(Unit, i, "HARMFUL");
+ local Name, rank, Texture, Applications, TypeName, Duration, expirationTime = UnitAura(Unit, i, "HARMFUL");
--local Name, rank, Texture, Applications, TypeName, Duration = UnitDebuff(Unit, i);
if Name then
- -- CoA: bleeds have no Blizzard dispel type. Re-tag them as "Bleed"
- -- when spellId matches DC.BleedSpellIDs (generated from coa-db).
- -- Only overrides typeless debuffs — a real Magic/Curse/etc tag wins.
- if (not TypeName or TypeName == "") and spellId and DC.BleedSpellIDs and DC.BleedSpellIDs[spellId] then
- TypeName = "Bleed";
- end
return Name, TypeName, Applications, Texture, expirationTime;
else
return false, false, false, false, false;
diff --git a/Decursive/Decursive.toc b/Decursive/Decursive.toc
index 2d335a9..7349c73 100644
--- a/Decursive/Decursive.toc
+++ b/Decursive/Decursive.toc
@@ -18,7 +18,7 @@
## SavedVariables: DecursiveDB
-## Version: Asc-1.1.8-coa (orig 2.5.1-6-gd3885c5)
+## Version: Asc-1.1.2-coa (orig 2.5.1-6-gd3885c5)
## Author: Archarodim
## X-License: All Rights Reserved
@@ -50,7 +50,6 @@ Dcr_DIAG.xml
Localization\load.xml
DCR_init.lua
-Dcr_BleedIDs.lua
Dcr_LDB.lua
Dcr_utils.lua
diff --git a/Decursive/LibStub/LibStub.lua b/Decursive/LibStub/LibStub.lua
index d50c267..0a41ac0 100644
--- a/Decursive/LibStub/LibStub.lua
+++ b/Decursive/LibStub/LibStub.lua
@@ -7,24 +7,24 @@ if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
-
+
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
- minor = assert(tonumber(string.match(minor, "%d+")), "Minor version must either be a number or contain a number.")
-
+ minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
-
+
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
-
+
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
diff --git a/Decursive/Libs/AceAddon-3.0/AceAddon-3.0.lua b/Decursive/Libs/AceAddon-3.0/AceAddon-3.0.lua
index 00e4e48..6c89654 100644
--- a/Decursive/Libs/AceAddon-3.0/AceAddon-3.0.lua
+++ b/Decursive/Libs/AceAddon-3.0/AceAddon-3.0.lua
@@ -6,31 +6,31 @@
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
--- -- A small (but complete) addon, that doesn't do anything,
+-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
---
+--
-- function MyAddon:OnInitialize()
--- -- do init tasks here, like loading the Saved Variables,
+-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
---
+--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
--- -- Register Events, Hook functions, Create Frames, Get information from
+-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
--- -- You would probably only use an OnDisable if you want to
+-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
--- @release $Id$
+-- @release $Id: AceAddon-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
-local MAJOR, MINOR = "AceAddon-3.0", 13
+local MAJOR, MINOR = "AceAddon-3.0", 5
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceAddon then return end -- No Upgrade needed.
@@ -49,6 +49,10 @@ local select, pairs, next, type, unpack = select, pairs, next, type, unpack
local loadstring, assert, error = loadstring, assert, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
+
--[[
xpcall safecall implementation
]]
@@ -58,12 +62,43 @@ local function errorhandler(err)
return geterrorhandler()(err)
end
+local function CreateDispatcher(argCount)
+ local code = [[
+ local xpcall, eh = ...
+ local method, ARGS
+ local function call() return method(ARGS) end
+
+ local function dispatch(func, ...)
+ method = func
+ if not method then return end
+ ARGS = ...
+ return xpcall(call, eh)
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS = {}
+ for i = 1, argCount do ARGS[i] = "arg"..i end
+ code = code:gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
+end})
+Dispatchers[0] = function(func)
+ return xpcall(func, errorhandler)
+end
+
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
- return xpcall(func, errorhandler, ...)
+ return Dispatchers[select('#', ...)](func, ...)
end
end
@@ -71,27 +106,17 @@ end
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
-- used in the addon metatable
-local function addontostring( self ) return self.name end
-
--- Check if the addon is queued for initialization
-local function queuedForInitialization(addon)
- for i = 1, #AceAddon.initializequeue do
- if AceAddon.initializequeue[i] == addon then
- return true
- end
- end
- return false
-end
+local function addontostring( self ) return self.name end
--- Create a new AceAddon-3.0 addon.
--- Any libraries you specified will be embeded, and the addon will be scheduled for
+-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
--- @usage
+-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
@@ -111,10 +136,10 @@ function AceAddon:NewAddon(objectorname, ...)
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
- if self.addons[name] then
+ if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
-
+
object = object or {}
object.name = name
@@ -124,15 +149,14 @@ function AceAddon:NewAddon(objectorname, ...)
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
-
+
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
- object.orderedModules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
-
+
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
@@ -143,7 +167,7 @@ end
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
--- @usage
+-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
@@ -198,7 +222,7 @@ end
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
--- @usage
+-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
@@ -221,23 +245,23 @@ local function IsModuleTrue(self) return true end
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
--- @usage
+-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
---
+--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
-
+
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
-
+
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
-
+
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
@@ -252,24 +276,23 @@ function NewModule(self, name, prototype, ...)
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
-
+
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
-
+
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
- tinsert(self.orderedModules, module)
-
+
return module
end
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
--- @paramsig
--- @usage
+-- @paramsig
+-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
@@ -281,20 +304,15 @@ end
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
--- @paramsig
--- @usage
+-- @paramsig
+-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
-
- -- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still
- -- it'll be enabled after the init process
- if not queuedForInitialization(self) then
- return AceAddon:EnableAddon(self)
- end
+ return AceAddon:EnableAddon(self)
end
--- Disables the Addon, if possible, return true or false depending on success.
@@ -302,8 +320,8 @@ end
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
--- @paramsig
--- @usage
+-- @paramsig
+-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
@@ -316,7 +334,7 @@ end
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
--- @usage
+-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
@@ -334,7 +352,7 @@ end
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
--- @usage
+-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
@@ -353,7 +371,7 @@ end
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
--- @usage
+-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
@@ -372,7 +390,7 @@ end
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
--- @usage
+-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
@@ -392,7 +410,7 @@ end
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
--- @usage
+-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
@@ -424,8 +442,8 @@ end
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
--- @paramsig
--- @usage
+-- @paramsig
+-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
@@ -434,13 +452,13 @@ local function IterateModules(self) return pairs(self.modules) end
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
--- @paramsig
+-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
--- @paramsig
--- @usage
+-- @paramsig
+-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
@@ -471,34 +489,32 @@ local pmixins = {
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
-function Embed(target, skipPMixins)
+function Embed(target)
for k, v in pairs(mixins) do
target[k] = v
end
- if not skipPMixins then
- for k, v in pairs(pmixins) do
- target[k] = target[k] or v
- end
+ for k, v in pairs(pmixins) do
+ target[k] = target[k] or v
end
end
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
--- It will call the **OnInitialize** function on the addon object (if present),
+-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
---
+--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
-
+
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
-
+
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
@@ -506,7 +522,7 @@ end
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
--- It will call the **OnEnable** function on the addon object (if present),
+-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
@@ -516,12 +532,12 @@ end
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
-
+
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
-
+
safecall(addon.OnEnable, addon)
-
+
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
@@ -529,11 +545,10 @@ function AceAddon:EnableAddon(addon)
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
-
+
-- enable possible modules.
- local modules = addon.orderedModules
- for i = 1, #modules do
- self:EnableAddon(modules[i])
+ for name, module in pairs(addon.modules) do
+ self:EnableAddon(module)
end
end
return self.statuses[addon.name] -- return true if we're disabled
@@ -541,41 +556,40 @@ end
-- - Disable the addon
-- Note: This function is only used internally.
--- It will call the **OnDisable** function on the addon object (if present),
+-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
--- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
+-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
-
+
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
-
+
safecall( addon.OnDisable, addon )
-
+
-- make sure we're still disabling...
- if not self.statuses[addon.name] then
+ if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
- local modules = addon.orderedModules
- for i = 1, #modules do
- self:DisableAddon(modules[i])
+ for name, module in pairs(addon.modules) do
+ self:DisableAddon(module)
end
end
-
+
return not self.statuses[addon.name] -- return true if we're disabled
end
--- Get an iterator over all registered addons.
--- @usage
+-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
@@ -583,7 +597,7 @@ end
function AceAddon:IterateAddons() return pairs(self.addons) end
--- Get an iterator over the internal status registry.
--- @usage
+-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
@@ -597,20 +611,9 @@ function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
--- Blizzard AddOns which can load very early in the loading process and mess with Ace3 addon loading
-local BlizzardEarlyLoadAddons = {
- Blizzard_DebugTools = true,
- Blizzard_TimeManager = true,
- Blizzard_BattlefieldMap = true,
- Blizzard_MapCanvas = true,
- Blizzard_SharedMapDataProviders = true,
- Blizzard_CombatLog = true,
-}
-
-- Event Handling
local function onEvent(this, event, arg1)
- -- 2020-08-28 nevcairiel - ignore the load event of Blizzard addons which occur early in the loading process
- if (event == "ADDON_LOADED" and (arg1 == nil or not BlizzardEarlyLoadAddons[arg1])) or event == "PLAYER_LOGIN" then
+ if event == "ADDON_LOADED" or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
@@ -619,7 +622,7 @@ local function onEvent(this, event, arg1)
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
-
+
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
@@ -635,15 +638,5 @@ AceAddon.frame:SetScript("OnEvent", onEvent)
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
- Embed(addon, true)
-end
-
--- 2010-10-27 nevcairiel - add new "orderedModules" table
-if oldminor and oldminor < 10 then
- for name, addon in pairs(AceAddon.addons) do
- addon.orderedModules = {}
- for module_name, module in pairs(addon.modules) do
- tinsert(addon.orderedModules, module)
- end
- end
+ Embed(addon)
end
diff --git a/Decursive/Libs/AceComm-3.0/AceComm-3.0.lua b/Decursive/Libs/AceComm-3.0/AceComm-3.0.lua
index faab36c..ad5268f 100644
--- a/Decursive/Libs/AceComm-3.0/AceComm-3.0.lua
+++ b/Decursive/Libs/AceComm-3.0/AceComm-3.0.lua
@@ -2,14 +2,14 @@
-- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
-- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
--
--- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
+-- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceComm itself.\\
-- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceComm.
-- @class file
-- @name AceComm-3.0
--- @release $Id$
+-- @release $Id: AceComm-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
--[[ AceComm-3.0
@@ -17,23 +17,24 @@ TODO: Time out old data rotting around from dead senders? Not a HUGE deal since
]]
-local CallbackHandler = LibStub("CallbackHandler-1.0")
-local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
+local MAJOR, MINOR = "AceComm-3.0", 6
-local MAJOR, MINOR = "AceComm-3.0", 14
local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceComm then return end
+local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
+
-- Lua APIs
local type, next, pairs, tostring = type, next, pairs, tostring
local strsub, strfind = string.sub, string.find
-local match = string.match
local tinsert, tconcat = table.insert, table.concat
local error, assert = error, assert
--- WoW APIs
-local Ambiguate = Ambiguate
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: LibStub, DEFAULT_CHAT_FRAME, geterrorhandler
AceComm.embeds = AceComm.embeds or {}
@@ -41,32 +42,21 @@ AceComm.embeds = AceComm.embeds or {}
local MSG_MULTI_FIRST = "\001"
local MSG_MULTI_NEXT = "\002"
local MSG_MULTI_LAST = "\003"
-local MSG_ESCAPE = "\004"
--- remove old structures (pre WoW 4.0)
-AceComm.multipart_origprefixes = nil
-AceComm.multipart_reassemblers = nil
+AceComm.multipart_origprefixes = AceComm.multipart_origprefixes or {} -- e.g. "Prefix\001"="Prefix", "Prefix\002"="Prefix"
+AceComm.multipart_reassemblers = AceComm.multipart_reassemblers or {} -- e.g. "Prefix\001"="OnReceiveMultipartFirst"
-- the multipart message spool: indexed by a combination of sender+distribution+
-AceComm.multipart_spool = AceComm.multipart_spool or {}
+AceComm.multipart_spool = AceComm.multipart_spool or {}
--- Register for Addon Traffic on a specified prefix
--- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
+-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
-- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
function AceComm:RegisterComm(prefix, method)
if method == nil then
method = "OnCommReceived"
end
- if #prefix > 16 then -- TODO: 15?
- error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
- end
- if C_ChatInfo then
- C_ChatInfo.RegisterAddonMessagePrefix(prefix)
- else
- RegisterAddonMessagePrefix(prefix)
- end
-
return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
end
@@ -85,55 +75,57 @@ function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callb
if not( type(prefix)=="string" and
type(text)=="string" and
type(distribution)=="string" and
- (target==nil or type(target)=="string" or type(target)=="number") and
- (prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
+ (target==nil or type(target)=="string") and
+ (prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
) then
error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
end
+
+ if strfind(prefix, "[\001-\009]") then
+ if strfind(prefix, "[\001-\003]") then
+ error("SendCommMessage: Characters \\001--\\003 in prefix are reserved for AceComm metadata", 2)
+ elseif not warnedPrefix then
+ -- I have some ideas about future extensions that require more control characters /mikk, 20090808
+ geterrorhandler()("SendCommMessage: Heads-up developers: Characters \\004--\\009 in prefix are reserved for AceComm future extension")
+ warnedPrefix = true
+ end
+ end
+
local textlen = #text
- local maxtextlen = 255 -- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
- local queueName = prefix
+ local maxtextlen = 254 - #prefix -- 254 is the max length of prefix + text that can be sent in one message
+ local queueName = prefix..distribution..(target or "")
local ctlCallback = nil
if callbackFn then
- ctlCallback = function(sent, sendResult)
- return callbackFn(callbackArg, sent, textlen, sendResult)
+ ctlCallback = function(sent)
+ return callbackFn(callbackArg, sent, textlen)
end
end
- local forceMultipart
- if match(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
- -- we need to escape the first character with a \004
- if textlen+1 > maxtextlen then -- would we go over the size limit?
- forceMultipart = true -- just make it multipart, no escape problems then
- else
- text = "\004" .. text
- end
- end
-
- if not forceMultipart and textlen <= maxtextlen then
+ if textlen <= maxtextlen then
-- fits all in one message
CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
else
- maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
+ maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix
-- first part
local chunk = strsub(text, 1, maxtextlen)
- CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
+ CTL:SendAddonMessage(prio, prefix..MSG_MULTI_FIRST, chunk, distribution, target, queueName, ctlCallback, maxtextlen)
-- continuation
local pos = 1+maxtextlen
+ local prefix2 = prefix..MSG_MULTI_NEXT
while pos+maxtextlen <= textlen do
chunk = strsub(text, pos, pos+maxtextlen-1)
- CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
+ CTL:SendAddonMessage(prio, prefix2, chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
pos = pos + maxtextlen
end
-- final part
chunk = strsub(text, pos)
- CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
+ CTL:SendAddonMessage(prio, prefix..MSG_MULTI_LAST, chunk, distribution, target, queueName, ctlCallback, textlen)
end
end
@@ -146,17 +138,17 @@ do
local compost = setmetatable({}, {__mode = "k"})
local function new()
local t = next(compost)
- if t then
+ if t then
compost[t]=nil
for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
t[i]=nil
end
return t
end
-
+
return {}
end
-
+
local function lostdatawarning(prefix,sender,where)
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
end
@@ -164,14 +156,14 @@ do
function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
-
+
--[[
- if spool[key] then
+ if spool[key] then
lostdatawarning(prefix,sender,"First")
-- continue and overwrite
end
--]]
-
+
spool[key] = message -- plain string for now
end
@@ -179,7 +171,7 @@ do
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
local olddata = spool[key]
-
+
if not olddata then
--lostdatawarning(prefix,sender,"Next")
return
@@ -200,14 +192,14 @@ do
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
local olddata = spool[key]
-
+
if not olddata then
--lostdatawarning(prefix,sender,"End")
return
end
spool[key] = nil
-
+
if type(olddata) == "table" then
-- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
tinsert(olddata, message)
@@ -230,31 +222,47 @@ end
----------------------------------------
if not AceComm.callbacks then
+ -- ensure that 'prefix to watch' table is consistent with registered
+ -- callbacks
+ AceComm.__prefixes = {}
+
AceComm.callbacks = CallbackHandler:New(AceComm,
"_RegisterComm",
"UnregisterComm",
"UnregisterAllComm")
end
-AceComm.callbacks.OnUsed = nil
-AceComm.callbacks.OnUnused = nil
+function AceComm.callbacks:OnUsed(target, prefix)
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_FIRST] = prefix
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_FIRST] = "OnReceiveMultipartFirst"
+
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_NEXT] = prefix
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_NEXT] = "OnReceiveMultipartNext"
+
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_LAST] = prefix
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_LAST] = "OnReceiveMultipartLast"
+end
-local function OnEvent(self, event, prefix, message, distribution, sender)
+function AceComm.callbacks:OnUnused(target, prefix)
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_FIRST] = nil
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_FIRST] = nil
+
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_NEXT] = nil
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_NEXT] = nil
+
+ AceComm.multipart_origprefixes[prefix..MSG_MULTI_LAST] = nil
+ AceComm.multipart_reassemblers[prefix..MSG_MULTI_LAST] = nil
+end
+
+local function OnEvent(this, event, ...)
if event == "CHAT_MSG_ADDON" then
- sender = Ambiguate(sender, "none")
- local control, rest = match(message, "^([\001-\009])(.*)")
- if control then
- if control==MSG_MULTI_FIRST then
- AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
- elseif control==MSG_MULTI_NEXT then
- AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
- elseif control==MSG_MULTI_LAST then
- AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
- elseif control==MSG_ESCAPE then
- AceComm.callbacks:Fire(prefix, rest, distribution, sender)
- else
- -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
- end
+ local prefix,message,distribution,sender = ...
+ local reassemblername = AceComm.multipart_reassemblers[prefix]
+ if reassemblername then
+ -- multipart: reassemble
+ local aceCommReassemblerFunc = AceComm[reassemblername]
+ local origprefix = AceComm.multipart_origprefixes[prefix]
+ aceCommReassemblerFunc(AceComm, origprefix, message, distribution, sender)
else
-- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
AceComm.callbacks:Fire(prefix, message, distribution, sender)
diff --git a/Decursive/Libs/AceComm-3.0/ChatThrottleLib.lua b/Decursive/Libs/AceComm-3.0/ChatThrottleLib.lua
index 6e89a6a..b0afc92 100644
--- a/Decursive/Libs/AceComm-3.0/ChatThrottleLib.lua
+++ b/Decursive/Libs/AceComm-3.0/ChatThrottleLib.lua
@@ -3,7 +3,7 @@
--
-- Manages AddOn chat output to keep player from getting kicked off.
--
--- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
+-- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
--
-- Priorities get an equal share of available bandwidth when fully loaded.
@@ -20,10 +20,8 @@
--
-- Can run as a standalone addon also, but, really, just embed it! :-)
--
--- LICENSE: ChatThrottleLib is released into the Public Domain
---
-local CTL_VERSION = 31
+local CTL_VERSION = 21
local _G = _G
@@ -73,8 +71,8 @@ local math_min = math.min
local math_max = math.max
local next = next
local strlen = string.len
-local GetFramerate = GetFramerate
-local unpack,type,pairs,wipe = unpack,type,pairs,table.wipe
+local GetFrameRate = GetFrameRate
+
-----------------------------------------------------------------------
@@ -113,41 +111,28 @@ function Ring:Remove(obj)
end
end
--- Note that this is local because there's no upgrade logic for existing ring
--- metatables, and this isn't present on rings created in versions older than
--- v25.
-local function Ring_Link(self, other) -- Move and append all contents of another ring to this ring
- if not self.pos then
- -- This ring is empty, so just transfer ownership.
- self.pos = other.pos
- other.pos = nil
- elseif other.pos then
- -- Our tail should point to their head, and their tail to our head.
- self.pos.prev.next, other.pos.prev.next = other.pos, self.pos
- -- Our head should point to their tail, and their head to our tail.
- self.pos.prev, other.pos.prev = other.pos.prev, self.pos.prev
- other.pos = nil
- end
-end
-
-----------------------------------------------------------------------
--- Recycling bin for pipes
--- A pipe is a plain integer-indexed queue of messages
--- Pipes normally live in Rings of pipes (3 rings total, one per priority)
+-- Recycling bin for pipes
+-- A pipe is a plain integer-indexed queue, which also happens to be a ring member
ChatThrottleLib.PipeBin = nil -- pre-v19, drastically different
local PipeBin = setmetatable({}, {__mode="k"})
local function DelPipe(pipe)
+ for i = #pipe, 1, -1 do
+ pipe[i] = nil
+ end
+ pipe.prev = nil
+ pipe.next = nil
+
PipeBin[pipe] = true
end
local function NewPipe()
local pipe = next(PipeBin)
if pipe then
- wipe(pipe)
PipeBin[pipe] = nil
return pipe
end
@@ -184,7 +169,7 @@ end
-- Initialize queues, set up frame for OnUpdate, etc
-function ChatThrottleLib:Init()
+function ChatThrottleLib:Init()
-- Set up queues
if not self.Prio then
@@ -194,13 +179,6 @@ function ChatThrottleLib:Init()
self.Prio["BULK"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
end
- if not self.BlockedQueuesDelay then
- -- v25: Add blocked queues to rings to handle new client throttles.
- for _, Prio in pairs(self.Prio) do
- Prio.Blocked = Ring:New()
- end
- end
-
-- v4: total send counters per priority
for _, Prio in pairs(self.Prio) do
Prio.nTotalSent = Prio.nTotalSent or 0
@@ -223,7 +201,6 @@ function ChatThrottleLib:Init()
self.Frame:SetScript("OnEvent", self.OnEvent) -- v11: Monitor P_E_W so we can throttle hard for a few seconds
self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
self.OnUpdateDelay = 0
- self.BlockedQueuesDelay = 0
self.LastAvailUpdate = GetTime()
self.HardThrottlingBeginTime = GetTime() -- v11: Throttle hard for a few seconds after startup
@@ -232,43 +209,14 @@ function ChatThrottleLib:Init()
-- Use secure hooks as of v16. Old regular hook support yanked out in v21.
self.securelyHooked = true
--SendChatMessage
- if _G.C_ChatInfo and _G.C_ChatInfo.SendChatMessage then
- hooksecurefunc(_G.C_ChatInfo, "SendChatMessage", function(...)
- return ChatThrottleLib.Hook_SendChatMessage(...)
- end)
- else
- hooksecurefunc("SendChatMessage", function(...)
- return ChatThrottleLib.Hook_SendChatMessage(...)
- end)
- end
+ hooksecurefunc("SendChatMessage", function(...)
+ return ChatThrottleLib.Hook_SendChatMessage(...)
+ end)
--SendAddonMessage
- hooksecurefunc(_G.C_ChatInfo, "SendAddonMessage", function(...)
+ hooksecurefunc("SendAddonMessage", function(...)
return ChatThrottleLib.Hook_SendAddonMessage(...)
end)
end
-
- -- v26: Hook SendAddonMessageLogged for traffic logging
- if not self.securelyHookedLogged then
- self.securelyHookedLogged = true
- hooksecurefunc(_G.C_ChatInfo, "SendAddonMessageLogged", function(...)
- return ChatThrottleLib.Hook_SendAddonMessageLogged(...)
- end)
- end
-
- -- v29: Hook BNSendGameData for traffic logging
- if not self.securelyHookedBNGameData then
- self.securelyHookedBNGameData = true
- if _G.C_BattleNet and _G.C_BattleNet.SendGameData then
- hooksecurefunc(_G.C_BattleNet, "SendGameData", function(...)
- return ChatThrottleLib.Hook_BNSendGameData(...)
- end)
- else
- hooksecurefunc("BNSendGameData", function(...)
- return ChatThrottleLib.Hook_BNSendGameData(...)
- end)
- end
- end
-
self.nBypass = 0
end
@@ -297,12 +245,6 @@ function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destinati
self.avail = self.avail - size
self.nBypass = self.nBypass + size -- just a statistic
end
-function ChatThrottleLib.Hook_SendAddonMessageLogged(prefix, text, chattype, destination, ...)
- ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination, ...)
-end
-function ChatThrottleLib.Hook_BNSendGameData(destination, prefix, text)
- ChatThrottleLib.Hook_SendAddonMessage(prefix, text, "WHISPER", destination)
-end
@@ -339,93 +281,27 @@ end
-----------------------------------------------------------------------
-- Despooling logic
--- Reminder:
--- - We have 3 Priorities, each containing a "Ring" construct ...
--- - ... made up of N "Pipe"s (1 for each destination/pipename)
--- - and each pipe contains messages
-
-local SendAddonMessageResult = Enum.SendAddonMessageResult or {
- Success = 0,
- AddonMessageThrottle = 3,
- NotInGroup = 5,
- ChannelThrottle = 8,
- GeneralError = 9,
-}
-
-local function MapToSendResult(ok, ...)
- local result
-
- if not ok then
- -- The send function itself errored; don't look at anything else.
- result = SendAddonMessageResult.GeneralError
- else
- -- Grab the last return value from the send function and remap
- -- it from a boolean to an enum code. If there are no results,
- -- assume success (true).
-
- result = select(-1, true, ...)
-
- if result == true then
- result = SendAddonMessageResult.Success
- elseif result == false then
- result = SendAddonMessageResult.GeneralError
- end
- end
-
- return result
-end
-
-local function IsThrottledSendResult(result)
- return result == SendAddonMessageResult.AddonMessageThrottle
-end
-
--- A copy of this function exists in FrameXML, but for clarity it's here too.
-local function CallErrorHandler(...)
- return geterrorhandler()(...)
-end
-
-local function PerformSend(sendFunction, ...)
- bMyTraffic = true
- local sendResult = MapToSendResult(xpcall(sendFunction, CallErrorHandler, ...))
- bMyTraffic = false
- return sendResult
-end
function ChatThrottleLib:Despool(Prio)
local ring = Prio.Ring
while ring.pos and Prio.avail > ring.pos[1].nSize do
- local pipe = ring.pos
- local msg = pipe[1]
- local sendResult = PerformSend(msg.f, unpack(msg, 1, msg.n))
-
- if IsThrottledSendResult(sendResult) then
- -- Message was throttled; move the pipe into the blocked ring.
+ local msg = table_remove(Prio.Ring.pos, 1)
+ if not Prio.Ring.pos[1] then
+ local pipe = Prio.Ring.pos
Prio.Ring:Remove(pipe)
- Prio.Blocked:Add(pipe)
+ Prio.ByName[pipe.name] = nil
+ DelPipe(pipe)
else
- -- Dequeue message after submission.
- table_remove(pipe, 1)
- DelMsg(msg)
-
- if not pipe[1] then -- did we remove last msg in this pipe?
- Prio.Ring:Remove(pipe)
- Prio.ByName[pipe.name] = nil
- DelPipe(pipe)
- else
- ring.pos = ring.pos.next
- end
-
- -- Update bandwidth counters on successful sends.
- local didSend = (sendResult == SendAddonMessageResult.Success)
- if didSend then
- Prio.avail = Prio.avail - msg.nSize
- Prio.nTotalSent = Prio.nTotalSent + msg.nSize
- end
-
- -- Notify caller of message submission.
- if msg.callbackFn then
- securecallfunction(msg.callbackFn, msg.callbackArg, didSend, sendResult)
- end
+ Prio.Ring.pos = Prio.Ring.pos.next
+ end
+ Prio.avail = Prio.avail - msg.nSize
+ bMyTraffic = true
+ msg.f(unpack(msg, 1, msg.n))
+ bMyTraffic = false
+ Prio.nTotalSent = Prio.nTotalSent + msg.nSize
+ DelMsg(msg)
+ if msg.callbackFn then
+ msg.callbackFn (msg.callbackArg)
end
end
end
@@ -445,7 +321,6 @@ function ChatThrottleLib.OnUpdate(this,delay)
local self = ChatThrottleLib
self.OnUpdateDelay = self.OnUpdateDelay + delay
- self.BlockedQueuesDelay = self.BlockedQueuesDelay + delay
if self.OnUpdateDelay < 0.08 then
return
end
@@ -457,60 +332,40 @@ function ChatThrottleLib.OnUpdate(this,delay)
return -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
end
- -- Integrate blocked queues back into their rings periodically.
- if self.BlockedQueuesDelay >= 0.35 then
- for _, Prio in pairs(self.Prio) do
- Ring_Link(Prio.Ring, Prio.Blocked)
+ -- See how many of our priorities have queued messages (we only have 3, don't worry about the loop)
+ local n = 0
+ for prioname,Prio in pairs(self.Prio) do
+ if Prio.Ring.pos or Prio.avail < 0 then
+ n = n + 1
end
-
- self.BlockedQueuesDelay = 0
end
- -- See how many of our priorities have queued messages. This is split
- -- into two counters because priorities that consist only of blocked
- -- queues must keep our OnUpdate alive, but shouldn't count toward
- -- bandwidth distribution.
- local nSendablePrios = 0
- local nBlockedPrios = 0
-
- for prioname, Prio in pairs(self.Prio) do
- if Prio.Ring.pos then
- nSendablePrios = nSendablePrios + 1
- elseif Prio.Blocked.pos then
- nBlockedPrios = nBlockedPrios + 1
- end
-
- -- Collect unused bandwidth from priorities with nothing to send.
- if not Prio.Ring.pos then
+ -- Anything queued still?
+ if n<1 then
+ -- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
+ for prioname, Prio in pairs(self.Prio) do
self.avail = self.avail + Prio.avail
Prio.avail = 0
end
- end
-
- -- Bandwidth reclamation may take us back over the burst cap.
- self.avail = math_min(self.avail, self.BURST)
-
- -- If we can't currently send on any priorities, stop processing early.
- if nSendablePrios == 0 then
- -- If we're completely out of data to send, disable queue processing.
- if nBlockedPrios == 0 then
- self.bQueueing = false
- self.Frame:Hide()
- end
-
+ self.bQueueing = false
+ self.Frame:Hide()
return
end
-- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
- local avail = self.avail / nSendablePrios
+ local avail = self.avail/n
self.avail = 0
for prioname, Prio in pairs(self.Prio) do
- if Prio.Ring.pos then
+ if Prio.Ring.pos or Prio.avail < 0 then
Prio.avail = Prio.avail + avail
- self:Despool(Prio)
+ if Prio.Ring.pos and Prio.avail > Prio.Ring.pos[1].nSize then
+ self:Despool(Prio)
+ -- Note: We might not get here if the user-supplied callback function errors out! Take care!
+ end
end
end
+
end
@@ -519,6 +374,7 @@ end
-----------------------------------------------------------------------
-- Spooling logic
+
function ChatThrottleLib:Enqueue(prioname, pipename, msg)
local Prio = self.Prio[prioname]
local pipe = Prio.ByName[pipename]
@@ -535,6 +391,8 @@ function ChatThrottleLib:Enqueue(prioname, pipename, msg)
self.bQueueing = true
end
+
+
function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName, callbackFn, callbackArg)
if not self or not prio or not prefix or not text or not self.Prio[prio] then
error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix", "text"[, "chattype"[, "language"[, "destination"]]]', 2)
@@ -553,27 +411,20 @@ function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, languag
-- Check if there's room in the global available bandwidth gauge to send directly
if not self.bQueueing and nSize < self:UpdateAvail() then
- local sendResult = PerformSend(_G.C_ChatInfo.SendChatMessage or _G.SendChatMessage, text, chattype, language, destination)
-
- if not IsThrottledSendResult(sendResult) then
- local didSend = (sendResult == SendAddonMessageResult.Success)
-
- if didSend then
- self.avail = self.avail - nSize
- self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
- end
-
- if callbackFn then
- securecallfunction(callbackFn, callbackArg, didSend, sendResult)
- end
-
- return
+ self.avail = self.avail - nSize
+ bMyTraffic = true
+ _G.SendChatMessage(text, chattype, language, destination)
+ bMyTraffic = false
+ self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
+ if callbackFn then
+ callbackFn (callbackArg)
end
+ return
end
-- Message needs to be queued
local msg = NewMsg()
- msg.f = _G.C_ChatInfo.SendChatMessage or _G.SendChatMessage
+ msg.f = _G.SendChatMessage
msg[1] = text
msg[2] = chattype or "SAY"
msg[3] = language
@@ -583,36 +434,42 @@ function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, languag
msg.callbackFn = callbackFn
msg.callbackArg = callbackArg
- self:Enqueue(prio, queueName or prefix, msg)
+ self:Enqueue(prio, queueName or (prefix..(chattype or "SAY")..(destination or "")), msg)
end
-local function SendAddonMessageInternal(self, sendFunction, prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
- local nSize = #text + self.MSG_OVERHEAD
+function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
+ if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
+ error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
+ end
+ if callbackFn and type(callbackFn)~="function" then
+ error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
+ end
+
+ local nSize = prefix:len() + 1 + text:len();
+
+ if nSize>255 then
+ error("ChatThrottleLib:SendAddonMessage(): prefix + message length cannot exceed 254 bytes", 2)
+ end
+
+ nSize = nSize + self.MSG_OVERHEAD;
-- Check if there's room in the global available bandwidth gauge to send directly
if not self.bQueueing and nSize < self:UpdateAvail() then
- local sendResult = PerformSend(sendFunction, prefix, text, chattype, target)
-
- if not IsThrottledSendResult(sendResult) then
- local didSend = (sendResult == SendAddonMessageResult.Success)
-
- if didSend then
- self.avail = self.avail - nSize
- self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
- end
-
- if callbackFn then
- securecallfunction(callbackFn, callbackArg, didSend, sendResult)
- end
-
- return
+ self.avail = self.avail - nSize
+ bMyTraffic = true
+ _G.SendAddonMessage(prefix, text, chattype, target)
+ bMyTraffic = false
+ self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
+ if callbackFn then
+ callbackFn (callbackArg)
end
+ return
end
-- Message needs to be queued
local msg = NewMsg()
- msg.f = sendFunction
+ msg.f = _G.SendAddonMessage
msg[1] = prefix
msg[2] = text
msg[3] = chattype
@@ -622,65 +479,10 @@ local function SendAddonMessageInternal(self, sendFunction, prio, prefix, text,
msg.callbackFn = callbackFn
msg.callbackArg = callbackArg
- self:Enqueue(prio, queueName or prefix, msg)
+ self:Enqueue(prio, queueName or (prefix..chattype..(target or "")), msg)
end
-function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
- if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
- error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
- elseif callbackFn and type(callbackFn)~="function" then
- error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
- elseif #text>255 then
- error("ChatThrottleLib:SendAddonMessage(): message length cannot exceed 255 bytes", 2)
- end
-
- local sendFunction = _G.C_ChatInfo.SendAddonMessage
- SendAddonMessageInternal(self, sendFunction, prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
-end
-
-
-function ChatThrottleLib:SendAddonMessageLogged(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
- if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
- error('Usage: ChatThrottleLib:SendAddonMessageLogged("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
- elseif callbackFn and type(callbackFn)~="function" then
- error('ChatThrottleLib:SendAddonMessageLogged(): callbackFn: expected function, got '..type(callbackFn), 2)
- elseif #text>255 then
- error("ChatThrottleLib:SendAddonMessageLogged(): message length cannot exceed 255 bytes", 2)
- end
-
- local sendFunction = _G.C_ChatInfo.SendAddonMessageLogged
- SendAddonMessageInternal(self, sendFunction, prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
-end
-
-local function BNSendGameDataReordered(prefix, text, _, gameAccountID)
- local bnSendFunc = _G.C_BattleNet and _G.C_BattleNet.SendGameData or _G.BNSendGameData
- return bnSendFunc(gameAccountID, prefix, text)
-end
-
-function ChatThrottleLib:BNSendGameData(prio, prefix, text, chattype, gameAccountID, queueName, callbackFn, callbackArg)
- -- Note that this API is intentionally limited to 255 bytes of data
- -- for reasons of traffic fairness, which is less than the 4078 bytes
- -- BNSendGameData natively supports. Additionally, a chat type is required
- -- but must always be set to 'WHISPER' to match what is exposed by the
- -- receipt event.
- --
- -- If splitting messages, callers must also be aware that message
- -- delivery over BNSendGameData is unordered.
-
- if not self or not prio or not prefix or not text or not gameAccountID or not chattype or not self.Prio[prio] then
- error('Usage: ChatThrottleLib:BNSendGameData("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype", gameAccountID)', 2)
- elseif callbackFn and type(callbackFn)~="function" then
- error('ChatThrottleLib:BNSendGameData(): callbackFn: expected function, got '..type(callbackFn), 2)
- elseif #text>255 then
- error("ChatThrottleLib:BNSendGameData(): message length cannot exceed 255 bytes", 2)
- elseif chattype ~= "WHISPER" then
- error("ChatThrottleLib:BNSendGameData(): chat type must be 'WHISPER'", 2)
- end
-
- local sendFunction = BNSendGameDataReordered
- SendAddonMessageInternal(self, sendFunction, prio, prefix, text, chattype, gameAccountID, queueName, callbackFn, callbackArg)
-end
-----------------------------------------------------------------------
diff --git a/Decursive/Libs/AceConfig-3.0/AceConfig-3.0.lua b/Decursive/Libs/AceConfig-3.0/AceConfig-3.0.lua
index 1c9454a..09fdc32 100644
--- a/Decursive/Libs/AceConfig-3.0/AceConfig-3.0.lua
+++ b/Decursive/Libs/AceConfig-3.0/AceConfig-3.0.lua
@@ -3,7 +3,7 @@
-- as well as associate it with a slash command.
-- @class file
-- @name AceConfig-3.0
--- @release $Id$
+-- @release $Id: AceConfig-3.0.lua 963 2010-07-26 11:35:35Z mikk $
--[[
AceConfig-3.0
@@ -12,14 +12,13 @@ Very light wrapper library that combines all the AceConfig subcomponents into on
]]
-local cfgreg = LibStub("AceConfigRegistry-3.0")
-local cfgcmd = LibStub("AceConfigCmd-3.0")
-
-local MAJOR, MINOR = "AceConfig-3.0", 3
+local MAJOR, MINOR = "AceConfig-3.0", 2
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfig then return end
+local cfgreg = LibStub("AceConfigRegistry-3.0")
+local cfgcmd = LibStub("AceConfigCmd-3.0")
--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
@@ -27,7 +26,7 @@ if not AceConfig then return end
local pcall, error, type, pairs = pcall, error, type, pairs
-- -------------------------------------------------------------------
--- :RegisterOptionsTable(appName, options, slashcmd)
+-- :RegisterOptionsTable(appName, options, slashcmd, persist)
--
-- - appName - (string) application name
-- - options - table or function ref, see AceConfigRegistry
@@ -37,7 +36,7 @@ local pcall, error, type, pairs = pcall, error, type, pairs
-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
-- @paramsig appName, options [, slashcmd]
-- @param appName The application name for the config table.
--- @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/
+-- @param options The option table (or a function to generate one on demand)
-- @param slashcmd A slash command to register for the option table, or a table of slash commands.
-- @usage
-- local AceConfig = LibStub("AceConfig-3.0")
@@ -45,7 +44,7 @@ local pcall, error, type, pairs = pcall, error, type, pairs
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
if not ok then error(msg, 2) end
-
+
if slashcmd then
if type(slashcmd) == "table" then
for _,cmd in pairs(slashcmd) do
diff --git a/Decursive/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua b/Decursive/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
index 9e883a2..e764a99 100644
--- a/Decursive/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
+++ b/Decursive/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
@@ -1,7 +1,7 @@
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
-- @class file
-- @name AceConfigCmd-3.0
--- @release $Id$
+-- @release $Id: AceConfigCmd-3.0.lua 904 2009-12-13 11:56:37Z nevcairiel $
--[[
AceConfigCmd-3.0
@@ -14,9 +14,8 @@ REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
-- TODO: plugin args
-local cfgreg = LibStub("AceConfigRegistry-3.0")
-local MAJOR, MINOR = "AceConfigCmd-3.0", 14
+local MAJOR, MINOR = "AceConfigCmd-3.0", 12
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigCmd then return end
@@ -24,6 +23,7 @@ if not AceConfigCmd then return end
AceConfigCmd.commands = AceConfigCmd.commands or {}
local commands = AceConfigCmd.commands
+local cfgreg = LibStub("AceConfigRegistry-3.0")
local AceConsole -- LoD
local AceConsoleName = "AceConsole-3.0"
@@ -37,10 +37,17 @@ local error, assert = error, assert
-- WoW APIs
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME
+
+
local L = setmetatable({}, { -- TODO: replace with proper locale
__index = function(self,k) return k end
})
+
+
local function print(msg)
(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
end
@@ -56,7 +63,7 @@ local funcmsg = "expected function or member name"
-- pickfirstset() - picks the first non-nil value and returns it
-local function pickfirstset(...)
+local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
@@ -113,7 +120,7 @@ local function callfunction(info, tab, methodtype, ...)
info.arg = tab.arg
info.option = tab
info.type = tab.type
-
+
if type(method)=="function" then
return method(info, ...)
else
@@ -124,7 +131,7 @@ end
-- do_final() - do the final step (set/execute) along with validation and confirmation
local function do_final(info, inputpos, tab, methodtype, ...)
- if info.validate then
+ if info.validate then
local res = callmethod(info,inputpos,tab,"validate",...)
if type(res)=="string" then
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
@@ -132,7 +139,7 @@ local function do_final(info, inputpos, tab, methodtype, ...)
end
end
-- console ignores .confirm
-
+
callmethod(info,inputpos,tab,methodtype, ...)
end
@@ -145,8 +152,8 @@ local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
if val~=nil then
if val==false then
val=nil
- elseif not types[type(val)] then
- err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
+ elseif not types[type(val)] then
+ err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
end
info[paramname] = val
info[paramname.."_at"] = depth
@@ -159,13 +166,13 @@ end
local dummytable={}
local function iterateargs(tab)
- if not tab.plugins then
- return pairs(tab.args)
+ if not tab.plugins then
+ return pairs(tab.args)
end
-
+
local argtabkey,argtab=next(tab.plugins)
local v
-
+
return function(_, k)
while argtab do
k,v = next(argtab, k)
@@ -199,18 +206,18 @@ local function showhelp(info, inputpos, tab, depth, noHead)
if not noHead then
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
end
-
+
local sortTbl = {} -- [1..n]=name
local refTbl = {} -- [name]=tableref
-
+
for k,v in iterateargs(tab) do
if not refTbl[k] then -- a plugin overriding something in .args
tinsert(sortTbl, k)
refTbl[k] = v
end
end
-
- tsort(sortTbl, function(one, two)
+
+ tsort(sortTbl, function(one, two)
local o1 = refTbl[one].order or 100
local o2 = refTbl[two].order or 100
if type(o1) == "function" or type(o1) == "string" then
@@ -233,7 +240,7 @@ local function showhelp(info, inputpos, tab, depth, noHead)
if o1==o2 then return tostring(one)optiontable
+-- handle() - selfrecursing function that processes input->optiontable
-- - depth - starts at 0
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
@@ -339,16 +346,16 @@ local function handle(info, inputpos, tab, depth, retfalse)
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
-
+
-------------------------------------------------------------------
-- Act according to .type of this table
-
+
if tab.type=="group" then
------------ group --------------------------------------------
-
+
if type(tab.args)~="table" then err(info, inputpos) end
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
-
+
-- grab next arg from input
local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
if not arg then
@@ -356,11 +363,11 @@ local function handle(info, inputpos, tab, depth, retfalse)
return
end
nextpos=nextpos+1
-
+
-- loop .args and try to find a key with a matching name
for k,v in iterateargs(tab) do
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
-
+
-- is this child an inline group? if so, traverse into it
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
info[depth+1] = k
@@ -376,8 +383,8 @@ local function handle(info, inputpos, tab, depth, retfalse)
return handle(info,nextpos,v,depth+1)
end
end
-
- -- no match
+
+ -- no match
if retfalse then
-- restore old infotable members and return false to indicate failure
info.handler,info.handler_at = oldhandler,oldhandler_at
@@ -388,40 +395,40 @@ local function handle(info, inputpos, tab, depth, retfalse)
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
return false
end
-
+
-- couldn't find the command, display error
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
return
end
-
- local strInput = strsub(info.input,inputpos);
-
+
+ local str = strsub(info.input,inputpos);
+
if tab.type=="execute" then
------------ execute --------------------------------------------
do_final(info, inputpos, tab, "func")
+
-
-
+
elseif tab.type=="input" then
------------ input --------------------------------------------
-
+
local res = true
if tab.pattern then
- if type(tab.pattern)~="string" then err(info, inputpos, "'pattern' - expected a string") end
- if not strmatch(strInput, tab.pattern) then
- usererr(info, inputpos, "'"..strInput.."' - " .. L["invalid input"])
+ if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
+ if not strmatch(str, tab.pattern) then
+ usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
return
end
end
+
+ do_final(info, inputpos, tab, "set", str)
+
- do_final(info, inputpos, tab, "set", strInput)
-
-
-
+
elseif tab.type=="toggle" then
------------ toggle --------------------------------------------
local b
- local str = strtrim(strlower(strInput))
+ local str = strtrim(strlower(str))
if str=="" then
b = callmethod(info, inputpos, tab, "get")
@@ -437,7 +444,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
else
b = not b
end
-
+
elseif str==L["on"] then
b = true
elseif str==L["off"] then
@@ -452,15 +459,15 @@ local function handle(info, inputpos, tab, depth, retfalse)
end
return
end
-
+
do_final(info, inputpos, tab, "set", b)
-
+
elseif tab.type=="range" then
------------ range --------------------------------------------
- local val = tonumber(strInput)
+ local val = tonumber(str)
if not val then
- usererr(info, inputpos, "'"..strInput.."' - "..L["expected number"])
+ usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
return
end
if type(info.step)=="number" then
@@ -474,21 +481,21 @@ local function handle(info, inputpos, tab, depth, retfalse)
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
return
end
-
+
do_final(info, inputpos, tab, "set", val)
-
+
elseif tab.type=="select" then
------------ select ------------------------------------
- local str = strtrim(strlower(strInput))
-
+ local str = strtrim(strlower(str))
+
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
-
+
if str == "" then
local b = callmethod(info, inputpos, tab, "get")
local fmt = "|cffffff78- [%s]|r %s"
@@ -505,7 +512,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
end
local ok
- for k,v in pairs(values) do
+ for k,v in pairs(values) do
if strlower(k)==str then
str = k -- overwrite with key (in case of case mismatches)
ok = true
@@ -516,20 +523,20 @@ local function handle(info, inputpos, tab, depth, retfalse)
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
return
end
-
+
do_final(info, inputpos, tab, "set", str)
-
+
elseif tab.type=="multiselect" then
------------ multiselect -------------------------------------------
- local str = strtrim(strlower(strInput))
-
+ local str = strtrim(strlower(str))
+
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
-
+
if str == "" then
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
@@ -543,7 +550,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
end
return
end
-
+
--build a table of the selections, checking that they exist
--parse for =on =off =default in the process
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
@@ -552,25 +559,25 @@ local function handle(info, inputpos, tab, depth, retfalse)
--parse option=on etc
local opt, val = v:match('(.+)=(.+)')
--get option if toggling
- if not opt then
- opt = v
+ if not opt then
+ opt = v
end
-
+
--check that the opt is valid
local ok
- for k in pairs(values) do
+ for k,v in pairs(values) do
if strlower(k)==opt then
opt = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
-
+
if not ok then
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
return
end
-
+
--check that if val was supplied it is valid
if val then
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
@@ -589,14 +596,14 @@ local function handle(info, inputpos, tab, depth, retfalse)
sels[opt] = true
end
end
-
+
for opt, val in pairs(sels) do
local newval
-
+
if (val == true) then
--toggle the option
local b = callmethod(info, inputpos, tab, "get", opt)
-
+
if tab.tristate then
--cycle in true, nil, false order
if b then
@@ -620,29 +627,22 @@ local function handle(info, inputpos, tab, depth, retfalse)
newval = nil
end
end
-
+
do_final(info, inputpos, tab, "set", opt, newval)
end
-
-
+
+
elseif tab.type=="color" then
------------ color --------------------------------------------
- local str = strtrim(strlower(strInput))
+ local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
end
-
+
local r, g, b, a
-
- local hasAlpha = tab.hasAlpha
- if type(hasAlpha) == "function" or type(hasAlpha) == "string" then
- info.hasAlpha = hasAlpha
- hasAlpha = callmethod(info, inputpos, tab, 'hasAlpha')
- info.hasAlpha = nil
- end
-
- if hasAlpha then
+
+ if tab.hasAlpha then
if str:len() == 8 and str:find("^%x*$") then
--parse a hex string
r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
@@ -655,7 +655,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
return
end
-
+
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
@@ -694,12 +694,12 @@ local function handle(info, inputpos, tab, depth, retfalse)
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
end
end
-
+
do_final(info, inputpos, tab, "set", r,g,b,a)
elseif tab.type=="keybinding" then
------------ keybinding --------------------------------------------
- local str = strtrim(strlower(strInput))
+ local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
@@ -730,7 +730,7 @@ end
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
-- -- Use AceConsole-3.0 to register a Chat Command
-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
---
+--
-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
-- function MyAddon:ChatCommand(input)
-- -- Assuming "MyOptions" is the appName of a valid options table
@@ -747,7 +747,7 @@ function AceConfigCmd:HandleCommand(slashcmd, appName, input)
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
end
local options = assert( optgetter("cmd", MAJOR) )
-
+
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
[0] = slashcmd,
appName = appName,
@@ -758,7 +758,7 @@ function AceConfigCmd:HandleCommand(slashcmd, appName, input)
uiType = "cmd",
uiName = MAJOR,
}
-
+
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
end
diff --git a/Decursive/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua b/Decursive/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
index 19772f0..b57ac89 100644
--- a/Decursive/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
+++ b/Decursive/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
@@ -1,13 +1,10 @@
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
-- @class file
-- @name AceConfigDialog-3.0
--- @release $Id$
+-- @release $Id: AceConfigDialog-3.0.lua 958 2010-07-03 10:22:29Z nevcairiel $
local LibStub = LibStub
-local gui = LibStub("AceGUI-3.0")
-local reg = LibStub("AceConfigRegistry-3.0")
-
-local MAJOR, MINOR = "AceConfigDialog-3.0", 92
+local MAJOR, MINOR = "AceConfigDialog-3.0", 49
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigDialog then return end
@@ -15,20 +12,28 @@ if not AceConfigDialog then return end
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
AceConfigDialog.Status = AceConfigDialog.Status or {}
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
-AceConfigDialog.tooltip = AceConfigDialog.tooltip or CreateFrame("GameTooltip", "AceConfigDialogTooltip", UIParent, "GameTooltipTemplate")
AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
+local gui = LibStub("AceGUI-3.0")
+local reg = LibStub("AceConfigRegistry-3.0")
+
-- Lua APIs
-local tinsert, tsort, tremove, wipe = table.insert, table.sort, table.remove, table.wipe
+local tconcat, tinsert, tsort, tremove = table.concat, table.insert, table.sort, table.remove
local strmatch, format = string.match, string.format
-local error = error
-local pairs, next, select, type, unpack, ipairs = pairs, next, select, type, unpack, ipairs
-local tostring, tonumber = tostring, tonumber
+local assert, loadstring, error = assert, loadstring, error
+local pairs, next, select, type, unpack, wipe = pairs, next, select, type, unpack, wipe
+local rawset, tostring, tonumber = rawset, tostring, tonumber
local math_min, math_max, math_floor = math.min, math.max, math.floor
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
+-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
+-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
+
local emptyTbl = {}
--[[
@@ -40,10 +45,39 @@ local function errorhandler(err)
return geterrorhandler()(err)
end
+local function CreateDispatcher(argCount)
+ local code = [[
+ local xpcall, eh = ...
+ local method, ARGS
+ local function call() return method(ARGS) end
+
+ local function dispatch(func, ...)
+ method = func
+ if not method then return end
+ ARGS = ...
+ return xpcall(call, eh)
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS = {}
+ for i = 1, argCount do ARGS[i] = "arg"..i end
+ code = code:gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
+end})
+Dispatchers[0] = function(func)
+ return xpcall(func, errorhandler)
+end
+
local function safecall(func, ...)
- if func then
- return xpcall(func, errorhandler, ...)
- end
+ return Dispatchers[select("#", ...)](func, ...)
end
local width_multiplier = 170
@@ -51,18 +85,18 @@ local width_multiplier = 170
--[[
Group Types
Tree - All Descendant Groups will all become nodes on the tree, direct child options will appear above the tree
- - Descendant Groups with inline=true and thier children will not become nodes
+ - Descendant Groups with inline=true and thier children will not become nodes
Tab - Direct Child Groups will become tabs, direct child options will appear above the tab control
- - Grandchild groups will default to inline unless specified otherwise
+ - Grandchild groups will default to inline unless specified otherwise
Select- Same as Tab but with entries in a dropdown rather than tabs
Inline Groups
- - Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
- - If declared on a direct child of a root node of a select group, they will appear above the group container control
- - When a group is displayed inline, all descendants will also be inline members of the group
+ - Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
+ - If declared on a direct child of a root node of a select group, they will appear above the group container control
+ - When a group is displayed inline, all descendants will also be inline members of the group
]]
@@ -91,7 +125,9 @@ do
end
function del(t)
--delcount = delcount + 1
- wipe(t)
+ for k in pairs(t) do
+ t[k] = nil
+ end
pool[t] = true
end
-- function cached()
@@ -147,7 +183,6 @@ local stringIsLiteral = {
width = true,
image = true,
fontSize = true,
- tooltipHyperlink = true
}
--Is Never a function or method
@@ -164,11 +199,11 @@ local allIsLiteral = {
local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
--get definition for the member
local inherits = isInherited[membername]
-
+
--get the member of the option, traversing the tree if it can be inherited
local member
-
+
if inherits then
local group = options
if group[membername] ~= nil then
@@ -183,21 +218,22 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
else
member = option[membername]
end
-
+
--check if we need to call a functon, or if we have a literal value
if ( not allIsLiteral[membername] ) and ( type(member) == "function" or ((not stringIsLiteral[membername]) and type(member) == "string") ) then
--We have a function to call
local info = new()
--traverse the options table, picking up the handler and filling the info with the path
+ local handler
local group = options
- local handler = group.handler
-
+ handler = group.handler or handler
+
for i = 1, #path do
group = GetSubOption(group, path[i])
info[i] = path[i]
handler = group.handler or handler
end
-
+
info.options = options
info.appName = appName
info[0] = appName
@@ -207,8 +243,8 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
info.type = option.type
info.uiType = "dialog"
info.uiName = MAJOR
-
- local a, b, c ,d
+
+ local a, b, c ,d
--using 4 returns for the get of a color type, increase if a type needs more
if type(member) == "function" then
--Call the function
@@ -225,8 +261,8 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
return a,b,c,d
else
--The value isnt a function to call, return it
- return member
- end
+ return member
+ end
end
--[[calls an options function that could be inherited, method name or function ref
@@ -286,12 +322,12 @@ local function compareOptions(a,b)
end
local OrderA, OrderB = tempOrders[a] or 100, tempOrders[b] or 100
if OrderA == OrderB then
- local NameA = (type(tempNames[a]) == "string") and tempNames[a] or ""
- local NameB = (type(tempNames[b]) == "string") and tempNames[b] or ""
+ local NameA = (type(tempNames[a] == "string") and tempNames[a]) or ""
+ local NameB = (type(tempNames[b] == "string") and tempNames[b]) or ""
return NameA:upper() < NameB:upper()
end
if OrderA < 0 then
- if OrderB >= 0 then
+ if OrderB > 0 then
return false
end
else
@@ -310,7 +346,7 @@ end
local function BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
tempOrders = new()
tempNames = new()
-
+
if group.plugins then
for plugin, t in pairs(group.plugins) do
for k, v in pairs(t) do
@@ -326,7 +362,7 @@ local function BuildSortedOptionsTable(group, keySort, opts, options, path, appN
end
end
end
-
+
for k, v in pairs(group.args) do
if not opts[k] then
tinsert(keySort, k)
@@ -357,7 +393,7 @@ local function DelTree(tree)
end
local function CleanUserData(widget, event)
-
+
local user = widget:GetUserDataTable()
if user.path then
@@ -388,16 +424,13 @@ local function CleanUserData(widget, event)
if user.grouplist then
del(user.grouplist)
end
- if user.orderlist then
- del(user.orderlist)
- end
end
end
-- - Gets a status table for the given appname and options path.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param path The path to the options (a table with all group keys)
--- @return
+-- @return
function AceConfigDialog:GetStatusTable(appName, path)
local status = self.Status
@@ -431,7 +464,7 @@ end
function AceConfigDialog:SelectGroup(appName, ...)
local path = new()
-
+
local app = reg:GetOptionsTable(appName)
if not app then
error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
@@ -443,9 +476,9 @@ function AceConfigDialog:SelectGroup(appName, ...)
status.groups = {}
end
status = status.groups
- local treevalue
- local treestatus
-
+ local treevalue
+ local treestatus
+
for n = 1, select("#",...) do
local key = select(n, ...)
@@ -472,12 +505,12 @@ function AceConfigDialog:SelectGroup(appName, ...)
--the selected group will be overwritten if a child is the final target but still needs to be open
treestatus.selected = treevalue
treestatus.groups[treevalue] = true
-
+
end
-
+
--move to the next group in the path
group = GetSubOption(group, key)
- if not group then
+ if not group then
break
end
tinsert(path, key)
@@ -487,10 +520,10 @@ function AceConfigDialog:SelectGroup(appName, ...)
end
status = status.groups
end
-
+
del(path)
reg:NotifyChange(appName)
-end
+end
local function OptionOnMouseOver(widget, event)
--show a tooltip/set the status bar to the desc text
@@ -499,163 +532,81 @@ local function OptionOnMouseOver(widget, event)
local options = user.options
local path = user.path
local appName = user.appName
- local tooltip = AceConfigDialog.tooltip
-
- tooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
-
- local tooltipHyperlink = GetOptionsMemberValue("tooltipHyperlink", opt, options, path, appName)
- if tooltipHyperlink then
- tooltip:SetHyperlink(tooltipHyperlink)
- tooltip:Show()
- return
- end
+ GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
local name = GetOptionsMemberValue("name", opt, options, path, appName)
local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
local descStyle = opt.descStyle
-
+
if descStyle and descStyle ~= "tooltip" then return end
-
- tooltip:SetText(name, 1, .82, 0, 1, true)
-
+
+ GameTooltip:SetText(name, 1, .82, 0, 1)
+
if opt.type == "multiselect" then
- tooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
- end
+ GameTooltip:AddLine(user.text,0.5, 0.5, 0.8, 1)
+ end
if type(desc) == "string" then
- tooltip:AddLine(desc, 1, 1, 1, true)
+ GameTooltip:AddLine(desc, 1, 1, 1, 1)
end
if type(usage) == "string" then
- tooltip:AddLine(usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
+ GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
end
- tooltip:Show()
+ GameTooltip:Show()
end
local function OptionOnMouseLeave(widget, event)
- AceConfigDialog.tooltip:Hide()
+ GameTooltip:Hide()
end
local function GetFuncName(option)
- if option.type == "execute" then
+ local type = option.type
+ if type == "execute" then
return "func"
else
return "set"
end
end
-do
- local InCombatLockdown = InCombatLockdown
- local frame = AceConfigDialog.popup
- if not frame or oldminor < 81 then
- frame = CreateFrame("Frame", nil, UIParent)
- AceConfigDialog.popup = frame
- frame:Hide()
- frame:SetPoint("CENTER", UIParent, "CENTER")
- frame:SetSize(320, 72)
- frame:EnableMouse(true) -- Do not allow click-through on the frame
- frame:SetFrameStrata("TOOLTIP")
- frame:SetFrameLevel(100) -- Lots of room to draw under it
- frame:SetScript("OnKeyDown", function(self, key)
- if key == "ESCAPE" then
- if not InCombatLockdown() then
- self:SetPropagateKeyboardInput(false)
- end
- if self.cancel:IsShown() then
- self.cancel:Click()
- else -- Showing a validation error
- self:Hide()
- end
- elseif not InCombatLockdown() then
- self:SetPropagateKeyboardInput(true)
- end
- end)
-
- local border = CreateFrame("Frame", nil, frame, "DialogBorderOpaqueTemplate")
- border:SetAllPoints(frame)
- frame:SetFixedFrameStrata(true)
- frame:SetFixedFrameLevel(true)
-
- local text = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
- text:SetSize(290, 0)
- text:SetPoint("TOP", 0, -16)
- frame.text = text
-
- local function newButton(newText)
- local button = CreateFrame("Button", nil, frame)
- button:SetSize(128, 21)
- button:SetNormalFontObject(GameFontNormal)
- button:SetHighlightFontObject(GameFontHighlight)
- button:SetNormalTexture("Interface\\Buttons\\UI-DialogBox-Button-Up")
- button:GetNormalTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
- button:SetPushedTexture("Interface\\Buttons\\UI-DialogBox-Button-Down")
- button:GetPushedTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
- button:SetHighlightTexture("Interface\\Buttons\\UI-DialogBox-Button-Highlight")
- button:GetHighlightTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
- button:SetText(newText)
- return button
- end
-
- local accept = newButton(ACCEPT)
- accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
- frame.accept = accept
-
- local cancel = newButton(CANCEL)
- cancel:SetPoint("LEFT", accept, "RIGHT", 13, 0)
- frame.cancel = cancel
- end
-end
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
- local frame = AceConfigDialog.popup
- frame:Show()
- frame.text:SetText(message)
- -- From StaticPopup.lua
- -- local height = 32 + text:GetHeight() + 2;
- -- height = height + 6 + accept:GetHeight()
- -- We add 32 + 2 + 6 + 21 (button height) == 61
- local height = 61 + frame.text:GetHeight()
- frame:SetHeight(height)
-
- frame.accept:ClearAllPoints()
- frame.accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
- frame.cancel:Show()
-
- local t = {...}
- local tCount = select("#", ...)
- frame.accept:SetScript("OnClick", function(self)
- safecall(func, unpack(t, 1, tCount)) -- Manually set count as unpack() stops on nil (bug with #table)
+ if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
+ StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
+ end
+ local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
+ for k in pairs(t) do
+ t[k] = nil
+ end
+ t.text = message
+ t.button1 = ACCEPT
+ t.button2 = CANCEL
+ local dialog, oldstrata
+ t.OnAccept = function()
+ safecall(func, unpack(t))
+ if dialog and oldstrata then
+ dialog:SetFrameStrata(oldstrata)
+ end
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
- frame:Hide()
- self:SetScript("OnClick", nil)
- frame.cancel:SetScript("OnClick", nil)
del(info)
- end)
- frame.cancel:SetScript("OnClick", function(self)
+ end
+ t.OnCancel = function()
+ if dialog and oldstrata then
+ dialog:SetFrameStrata(oldstrata)
+ end
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
- frame:Hide()
- self:SetScript("OnClick", nil)
- frame.accept:SetScript("OnClick", nil)
del(info)
- end)
-end
+ end
+ for i = 1, select("#", ...) do
+ t[i] = select(i, ...) or false
+ end
+ t.timeout = 0
+ t.whileDead = 1
+ t.hideOnEscape = 1
-local function validationErrorPopup(message)
- local frame = AceConfigDialog.popup
- frame:Show()
- frame.text:SetText(message)
- -- From StaticPopup.lua
- -- local height = 32 + text:GetHeight() + 2;
- -- height = height + 6 + accept:GetHeight()
- -- We add 32 + 2 + 6 + 21 (button height) == 61
- local height = 61 + frame.text:GetHeight()
- frame:SetHeight(height)
-
- frame.accept:ClearAllPoints()
- frame.accept:SetPoint("BOTTOM", frame, "BOTTOM", 0, 16)
- frame.cancel:Hide()
-
- frame.accept:SetScript("OnClick", function()
- frame:Hide()
- end)
+ dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
+ if dialog then
+ oldstrata = dialog:GetFrameStrata()
+ dialog:SetFrameStrata("TOOLTIP")
+ end
end
local function ActivateControl(widget, event, ...)
@@ -678,7 +629,7 @@ local function ActivateControl(widget, event, ...)
if group[funcname] ~= nil then
func = group[funcname]
end
- handler = group.handler
+ handler = group.handler or handler
confirm = group.confirm
validate = group.validate
for i = 1, #path do
@@ -726,7 +677,7 @@ local function ActivateControl(widget, event, ...)
end
end
end
-
+
local success
if validated and option.type ~= "execute" then
if type(validate) == "string" then
@@ -741,31 +692,38 @@ local function ActivateControl(widget, event, ...)
if not success then validated = false end
end
end
-
- if not validated or type(validated) == "string" then
- if not validated then
+
+ local rootframe = user.rootframe
+ if type(validated) == "string" then
+ --validate function returned a message to display
+ if rootframe.SetStatusText then
+ rootframe:SetStatusText(validated)
+ else
+ -- TODO: do something else.
+ end
+ PlaySound("igPlayerInviteDecline")
+ del(info)
+ return true
+ elseif not validated then
+ --validate returned false
+ if rootframe.SetStatusText then
if usage then
- validated = name..": "..usage
+ rootframe:SetStatusText(name..": "..usage)
else
if pattern then
- validated = name..": Expected "..pattern
+ rootframe:SetStatusText(name..": Expected "..pattern)
else
- validated = name..": Invalid Value"
+ rootframe:SetStatusText(name..": Invalid Value")
end
end
- end
-
- -- show validate message
- if user.rootframe.SetStatusText then
- user.rootframe:SetStatusText(validated)
else
- validationErrorPopup(validated)
+ -- TODO: do something else
end
- PlaySound(882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || _DECLINE is actually missing from the table
+ PlaySound("igPlayerInviteDecline")
del(info)
return true
else
-
+
local confirmText = option.confirmText
--call confirm func/method
if type(confirm) == "string" then
@@ -794,22 +752,22 @@ local function ActivateControl(widget, event, ...)
if type(confirm) == "boolean" then
if confirm then
if not confirmText then
- local option_name, desc = option.name, option.desc
- if type(option_name) == "function" then
- option_name = option_name(info)
+ local name, desc = option.name, option.desc
+ if type(name) == "function" then
+ name = name(info)
end
if type(desc) == "function" then
desc = desc(info)
end
- confirmText = option_name
+ confirmText = name
if desc then
confirmText = confirmText.." - "..desc
end
end
-
+
local iscustom = user.rootframe:GetUserData("iscustom")
local rootframe
-
+
if iscustom then
rootframe = user.rootframe
end
@@ -846,7 +804,7 @@ local function ActivateControl(widget, event, ...)
--full refresh of the frame, some controls dont cause this on all events
if option.type == "color" then
if event == "OnValueConfirmed" then
-
+
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
else
@@ -907,7 +865,7 @@ end
local function MultiControlOnClosed(widget, event, ...)
local user = widget:GetUserDataTable()
- if user.valuechanged and not widget:IsReleasing() then
+ if user.valuechanged then
local iscustom = user.rootframe:GetUserData("iscustom")
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
if iscustom then
@@ -975,7 +933,6 @@ end
]]
local function BuildSelect(group, options, path, appName)
local groups = new()
- local order = new()
local keySort = new()
local opts = new()
@@ -990,16 +947,15 @@ local function BuildSelect(group, options, path, appName)
local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then
groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
- tinsert(order, k)
end
path[#path] = nil
end
end
- del(opts)
del(keySort)
+ del(opts)
- return groups, order
+ return groups
end
local function BuildSubGroups(group, tree, options, path, appName)
@@ -1055,7 +1011,6 @@ local function BuildGroups(group, options, path, appName, recurse)
entry.value = k
entry.text = GetOptionsMemberValue("name", v, options, path, appName)
entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
- entry.iconCoords = GetOptionsMemberValue("iconCoords", v, options, path, appName)
entry.disabled = CheckOptionDisabled(v, options, path, appName)
tinsert(tree,entry)
if recurse and (v.childGroups or "tree") == "tree" then
@@ -1083,30 +1038,8 @@ local function InjectInfo(control, options, option, path, rootframe, appName)
control:SetCallback("OnRelease", CleanUserData)
control:SetCallback("OnLeave", OptionOnMouseLeave)
control:SetCallback("OnEnter", OptionOnMouseOver)
-
- -- forward custom arg data directly
- if control.SetCustomData and option.arg then
- safecall(control.SetCustomData, control, option.arg)
- end
end
-local function CreateControl(userControlType, fallbackControlType)
- local control
- if userControlType then
- control = gui:Create(userControlType)
- if not control then
- geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(userControlType)))
- end
- end
- if not control then
- control = gui:Create(fallbackControlType)
- end
- return control
-end
-
-local function sortTblAsStrings(x,y)
- return tostring(x) < tostring(y) -- Support numbers as keys
-end
--[[
options - root of the options table being fed
@@ -1138,7 +1071,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
else
GroupContainer = gui:Create("SimpleGroup")
end
-
+
GroupContainer.width = "fill"
GroupContainer:SetLayout("flow")
container:AddChild(GroupContainer)
@@ -1147,15 +1080,16 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
else
--Control to feed
local control
-
+
+ local name = GetOptionsMemberValue("name", v, options, path, appName)
+
if v.type == "execute" then
-
+
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
-
- local iconControl = type(image) == "string" or type(image) == "number"
- control = CreateControl(v.dialogControl or v.control, iconControl and "Icon" or "Button")
- if iconControl then
+
+ if type(image) == "string" then
+ control = gui:Create("Icon")
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end
@@ -1176,13 +1110,19 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetImageSize(width, height)
control:SetLabel(name)
else
+ control = gui:Create("Button")
control:SetText(name)
end
control:SetCallback("OnClick",ActivateControl)
elseif v.type == "input" then
- control = CreateControl(v.dialogControl or v.control, v.multiline and "MultiLineEditBox" or "EditBox")
-
+ local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox"
+ control = gui:Create(controlType)
+ if not control then
+ geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
+ control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox")
+ end
+
if v.multiline and control.SetNumLines then
control:SetNumLines(tonumber(v.multiline) or 4)
end
@@ -1195,22 +1135,22 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetText(text)
elseif v.type == "toggle" then
- control = CreateControl(v.dialogControl or v.control, "CheckBox")
+ control = gui:Create("CheckBox")
control:SetLabel(name)
control:SetTriState(v.tristate)
local value = GetOptionsMemberValue("get",v, options, path, appName)
control:SetValue(value)
control:SetCallback("OnValueChanged",ActivateControl)
-
+
if v.descStyle == "inline" then
local desc = GetOptionsMemberValue("desc", v, options, path, appName)
control:SetDescription(desc)
end
-
+
local image = GetOptionsMemberValue("image", v, options, path, appName)
local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName)
-
- if type(image) == "string" or type(image) == "number" then
+
+ if type(image) == "string" then
if type(imageCoords) == "table" then
control:SetImage(image, unpack(imageCoords))
else
@@ -1218,7 +1158,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end
end
elseif v.type == "range" then
- control = CreateControl(v.dialogControl or v.control, "Slider")
+ control = gui:Create("Slider")
control:SetLabel(name)
control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0)
control:SetIsPercent(v.isPercent)
@@ -1232,71 +1172,27 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
elseif v.type == "select" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
- local sorting = GetOptionsMemberValue("sorting", v, options, path, appName)
- if v.style == "radio" then
- local disabled = CheckOptionDisabled(v, options, path, appName)
- local width = GetOptionsMemberValue("width",v,options,path,appName)
- control = gui:Create("InlineGroup")
- control:SetLayout("Flow")
- control:SetTitle(name)
- control.width = "fill"
-
- control:PauseLayout()
- local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
- if not sorting then
- sorting = {}
- for value, text in pairs(values) do
- sorting[#sorting+1]=value
- end
- tsort(sorting, sortTblAsStrings)
- end
- for _, value in ipairs(sorting) do
- local text = values[value]
- local radio = gui:Create("CheckBox")
- radio:SetLabel(text)
- radio:SetUserData("value", value)
- radio:SetUserData("text", text)
- radio:SetDisabled(disabled)
- radio:SetType("radio")
- radio:SetValue(optionValue == value)
- radio:SetCallback("OnValueChanged", ActivateMultiControl)
- InjectInfo(radio, options, v, path, rootframe, appName)
- control:AddChild(radio)
- if width == "double" then
- radio:SetWidth(width_multiplier * 2)
- elseif width == "half" then
- radio:SetWidth(width_multiplier / 2)
- elseif (type(width) == "number") then
- radio:SetWidth(width_multiplier * width)
- elseif width == "full" then
- radio.width = "fill"
- else
- radio:SetWidth(width_multiplier)
- end
- end
- control:ResumeLayout()
- control:DoLayout()
- else
- control = CreateControl(v.dialogControl or v.control, "Dropdown")
- local itemType = v.itemControl
- if itemType and not gui:GetWidgetVersion(itemType) then
- geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType)))
- itemType = nil
- end
- control:SetLabel(name)
- control:SetList(values, sorting, itemType)
- local value = GetOptionsMemberValue("get",v, options, path, appName)
- if not values[value] then
- value = nil
- end
- control:SetValue(value)
- control:SetCallback("OnValueChanged", ActivateControl)
+ local controlType = v.dialogControl or v.control or "Dropdown"
+ control = gui:Create(controlType)
+ if not control then
+ geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
+ control = gui:Create("Dropdown")
end
+ control:SetLabel(name)
+ control:SetList(values)
+ local value = GetOptionsMemberValue("get",v, options, path, appName)
+ if not values[value] then
+ value = nil
+ end
+ control:SetValue(value)
+ control:SetCallback("OnValueChanged",ActivateControl)
elseif v.type == "multiselect" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
local disabled = CheckOptionDisabled(v, options, path, appName)
-
+
+ local controlType = v.dialogControl or v.control
+
local valuesort = new()
if values then
for value, text in pairs(values) do
@@ -1304,8 +1200,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end
end
tsort(valuesort)
-
- local controlType = v.dialogControl or v.control
+
if controlType then
control = gui:Create(controlType)
if not control then
@@ -1324,16 +1219,14 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:SetWidth(width_multiplier * 2)
elseif width == "half" then
control:SetWidth(width_multiplier / 2)
- elseif (type(width) == "number") then
- control:SetWidth(width_multiplier * width)
elseif width == "full" then
control.width = "fill"
else
control:SetWidth(width_multiplier)
end
--check:SetTriState(v.tristate)
- for s = 1, #valuesort do
- local key = valuesort[s]
+ for i = 1, #valuesort do
+ local key = valuesort[i]
local value = GetOptionsMemberValue("get",v, options, path, appName, key)
control:SetItemValue(key,value)
end
@@ -1345,8 +1238,8 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:PauseLayout()
local width = GetOptionsMemberValue("width",v,options,path,appName)
- for s = 1, #valuesort do
- local value = valuesort[s]
+ for i = 1, #valuesort do
+ local value = valuesort[i]
local text = values[value]
local check = gui:Create("CheckBox")
check:SetLabel(text)
@@ -1362,8 +1255,6 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
check:SetWidth(width_multiplier * 2)
elseif width == "half" then
check:SetWidth(width_multiplier / 2)
- elseif (type(width) == "number") then
- check:SetWidth(width_multiplier * width)
elseif width == "full" then
check.width = "fill"
else
@@ -1373,34 +1264,34 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
control:ResumeLayout()
control:DoLayout()
-
+
end
-
+
del(valuesort)
elseif v.type == "color" then
- control = CreateControl(v.dialogControl or v.control, "ColorPicker")
+ control = gui:Create("ColorPicker")
control:SetLabel(name)
- control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
+ control:SetHasAlpha(v.hasAlpha)
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnValueChanged",ActivateControl)
control:SetCallback("OnValueConfirmed",ActivateControl)
elseif v.type == "keybinding" then
- control = CreateControl(v.dialogControl or v.control, "Keybinding")
+ control = gui:Create("Keybinding")
control:SetLabel(name)
control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnKeyChanged",ActivateControl)
elseif v.type == "header" then
- control = CreateControl(v.dialogControl or v.control, "Heading")
+ control = gui:Create("Heading")
control:SetText(name)
control.width = "fill"
elseif v.type == "description" then
- control = CreateControl(v.dialogControl or v.control, "Label")
+ control = gui:Create("Label")
control:SetText(name)
-
+
local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
if fontSize == "medium" then
control:SetFontObject(GameFontHighlight)
@@ -1409,11 +1300,11 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
else -- small or invalid
control:SetFontObject(GameFontHighlightSmall)
end
-
+
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
-
- if type(image) == "string" or type(image) == "number" then
+
+ if type(image) == "string" then
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end
@@ -1433,23 +1324,18 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end
control:SetImageSize(width, height)
end
- local controlWidth = GetOptionsMemberValue("width",v,options,path,appName)
- control.width = not controlWidth and "fill"
+ local width = GetOptionsMemberValue("width",v,options,path,appName)
+ control.width = not width and "fill"
end
--Common Init
if control then
if control.width ~= "fill" then
local width = GetOptionsMemberValue("width",v,options,path,appName)
- local relWidth = GetOptionsMemberValue("relWidth",v,options,path,appName)
if width == "double" then
control:SetWidth(width_multiplier * 2)
elseif width == "half" then
control:SetWidth(width_multiplier / 2)
- elseif (type(width) == "number") then
- control:SetWidth(width_multiplier * width)
- elseif width == "relative" and relWidth then
- control:SetRelativeWidth(relWidth)
elseif width == "full" then
control.width = "fill"
else
@@ -1464,7 +1350,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
InjectInfo(control, options, v, path, rootframe, appName)
container:AddChild(control)
end
-
+
end
end
tremove(path)
@@ -1489,8 +1375,7 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
local option = user.option
local path = user.path
local appName = user.appName
- local tooltip = AceConfigDialog.tooltip
-
+
local feedpath = new()
for i = 1, #path do
feedpath[i] = path[i]
@@ -1505,50 +1390,49 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
-
- tooltip:SetOwner(button, "ANCHOR_NONE")
- tooltip:ClearAllPoints()
+
+ GameTooltip:SetOwner(button, "ANCHOR_NONE")
if widget.type == "TabGroup" then
- tooltip:SetPoint("BOTTOM",button,"TOP")
+ GameTooltip:SetPoint("BOTTOM",button,"TOP")
else
- tooltip:SetPoint("LEFT",button,"RIGHT")
+ GameTooltip:SetPoint("LEFT",button,"RIGHT")
end
- tooltip:SetText(name, 1, .82, 0, 1, true)
-
+ GameTooltip:SetText(name, 1, .82, 0, 1)
+
if type(desc) == "string" then
- tooltip:AddLine(desc, 1, 1, 1, true)
+ GameTooltip:AddLine(desc, 1, 1, 1, 1)
end
-
- tooltip:Show()
+
+ GameTooltip:Show()
end
local function TreeOnButtonLeave(widget, event, value, button)
- AceConfigDialog.tooltip:Hide()
+ GameTooltip:Hide()
end
local function GroupExists(appName, options, path, uniquevalue)
if not uniquevalue then return false end
-
+
local feedpath = new()
local temppath = new()
for i = 1, #path do
feedpath[i] = path[i]
end
-
+
BuildPath(feedpath, ("\001"):split(uniquevalue))
-
+
local group = options
for i = 1, #feedpath do
local v = feedpath[i]
temppath[i] = v
group = GetSubOption(group, v)
-
- if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
+
+ if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
del(feedpath)
del(temppath)
- return false
+ return false
end
end
del(feedpath)
@@ -1571,6 +1455,10 @@ local function GroupSelected(widget, event, uniquevalue)
end
BuildPath(feedpath, ("\001"):split(uniquevalue))
+ local group = options
+ for i = 1, #feedpath do
+ group = GetSubOption(group, feedpath[i])
+ end
widget:ReleaseChildren()
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
@@ -1667,7 +1555,7 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
tab:SetCallback("OnGroupSelected", GroupSelected)
tab:SetCallback("OnTabEnter", TreeOnButtonEnter)
tab:SetCallback("OnTabLeave", TreeOnButtonLeave)
-
+
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
@@ -1687,34 +1575,38 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
break
end
end
-
+
container:AddChild(tab)
elseif grouptype == "select" then
- local selectGroup = gui:Create("DropdownGroup")
- selectGroup:SetTitle(name)
- InjectInfo(selectGroup, options, group, path, rootframe, appName)
- selectGroup:SetCallback("OnGroupSelected", GroupSelected)
+ local select = gui:Create("DropdownGroup")
+ select:SetTitle(name)
+ InjectInfo(select, options, group, path, rootframe, appName)
+ select:SetCallback("OnGroupSelected", GroupSelected)
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
- selectGroup:SetStatusTable(status.groups)
- local grouplist, orderlist = BuildSelect(group, options, path, appName)
- selectGroup:SetGroupList(grouplist, orderlist)
- selectGroup:SetUserData("grouplist", grouplist)
- selectGroup:SetUserData("orderlist", orderlist)
-
- local firstgroup = orderlist[1]
- if firstgroup then
- selectGroup:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
+ select:SetStatusTable(status.groups)
+ local grouplist = BuildSelect(group, options, path, appName)
+ select:SetGroupList(grouplist)
+ select:SetUserData("grouplist", grouplist)
+ local firstgroup
+ for k, v in pairs(grouplist) do
+ if not firstgroup or k < firstgroup then
+ firstgroup = k
+ end
end
+
+ if firstgroup then
+ select:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
+ end
+
+ select.width = "fill"
+ select.height = "fill"
- selectGroup.width = "fill"
- selectGroup.height = "fill"
-
- container:AddChild(selectGroup)
+ container:AddChild(select)
--assume tree group by default
--if parenttype is tree then this group is already a node on that tree
@@ -1722,14 +1614,14 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
local tree = gui:Create("TreeGroup")
InjectInfo(tree, options, group, path, rootframe, appName)
tree:EnableButtonTooltips(false)
-
+
tree.width = "fill"
tree.height = "fill"
tree:SetCallback("OnGroupSelected", GroupSelected)
tree:SetCallback("OnButtonEnter", TreeOnButtonEnter)
tree:SetCallback("OnButtonLeave", TreeOnButtonLeave)
-
+
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
@@ -1770,7 +1662,7 @@ local function RefreshOnUpdate(this)
end
this.closing[appName] = nil
end
-
+
if this.closeAll then
for k, v in pairs(AceConfigDialog.OpenFrames) do
if not this.closeAllOverride[k] then
@@ -1780,7 +1672,7 @@ local function RefreshOnUpdate(this)
this.closeAll = nil
wipe(this.closeAllOverride)
end
-
+
for appName in pairs(this.apps) do
if AceConfigDialog.OpenFrames[appName] then
local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable()
@@ -1865,10 +1757,10 @@ function AceConfigDialog:Open(appName, container, ...)
local options = app("dialog", MAJOR)
local f
-
+
local path = new()
local name = GetOptionsMemberValue("name", options, options, path, appName)
-
+
--If an optional path is specified add it to the path table before feeding the options
--as container is optional as well it may contain the first element of the path
if type(container) == "string" then
@@ -1878,15 +1770,7 @@ function AceConfigDialog:Open(appName, container, ...)
for n = 1, select("#",...) do
tinsert(path, (select(n, ...)))
end
-
- local option = options
- if type(container) == "table" and container.type == "BlizOptionsGroup" and #path > 0 then
- for i = 1, #path do
- option = options.args[path[i]]
- end
- name = format("%s - %s", name, GetOptionsMemberValue("name", option, options, path, appName))
- end
-
+
--if a container is given feed into that
if container then
f = container
@@ -1942,19 +1826,17 @@ end
-- convert pre-39 BlizOptions structure to the new format
if oldminor and oldminor < 39 and AceConfigDialog.BlizOptions then
local old = AceConfigDialog.BlizOptions
- local newOpt = {}
+ local new = {}
for key, widget in pairs(old) do
local appName = widget:GetUserData("appName")
- if not newOpt[appName] then newOpt[appName] = {} end
- newOpt[appName][key] = widget
+ if not new[appName] then new[appName] = {} end
+ new[appName][key] = widget
end
- AceConfigDialog.BlizOptions = newOpt
+ AceConfigDialog.BlizOptions = new
else
AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {}
end
-AceConfigDialog.BlizOptionsIDMap = AceConfigDialog.BlizOptionsIDMap or {}
-
local function FeedToBlizPanel(widget, event)
local path = widget:GetUserData("path")
AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(path or emptyTbl))
@@ -1976,30 +1858,29 @@ end
-- has to be a head-level note.
--
-- This function returns a reference to the container frame registered with the Interface
--- Options, as well as the registered ID. You can use the ID to open the options with
--- the API function `Settings.OpenToCategory`.
+-- Options. You can use this reference to open the options with the API function
+-- `InterfaceOptionsFrame_OpenToCategory`.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param name A descriptive name to display in the options tree (defaults to appName)
-- @param parent The parent to use in the interface options tree.
-- @param ... The path in the options table to feed into the interface options panel.
--- @return The reference to the frame registered into the Interface Options.
--- @return The category ID to pass to Settings.OpenToCategory
+-- @return The reference to the frame registered into the Interface Options.
function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
local BlizOptions = AceConfigDialog.BlizOptions
- local BlizOptionsIDMap = AceConfigDialog.BlizOptionsIDMap
-
+
local key = appName
for n = 1, select("#", ...) do
key = key.."\001"..select(n, ...)
end
-
+
if not BlizOptions[appName] then
BlizOptions[appName] = {}
end
-
+
if not BlizOptions[appName][key] then
local group = gui:Create("BlizOptionsGroup")
BlizOptions[appName][key] = group
+ group:SetName(name or appName, parent)
group:SetTitle(name or appName)
group:SetUserData("appName", appName)
@@ -2012,42 +1893,8 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
end
group:SetCallback("OnShow", FeedToBlizPanel)
group:SetCallback("OnHide", ClearBlizPanel)
-
- local categoryName = name or appName
- -- CoA-compat: the Settings.* API (GetCategory / RegisterCanvasLayoutCategory /
- -- RegisterCanvasLayoutSubcategory / RegisterAddOnCategory) is a retail-only
- -- (Dragonflight+) replacement for the WotLK-era InterfaceOptions_AddCategory.
- -- On the 3.3.5-based CoA client Settings is nil, so fall back to the legacy API.
- if Settings and Settings.GetCategory then
- if parent then
- local parentID = BlizOptionsIDMap[parent] or parent
- local category = Settings.GetCategory(parentID)
- if not category then
- error(("The parent category '%s' was not found"):format(parent), 2)
- end
- local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName)
- group:SetName(subcategory.ID, parentID)
- else
- if BlizOptionsIDMap[categoryName] then
- error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2)
- end
-
- local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName)
- if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then
- -- override the ID so the name can be used in Settings.OpenToCategory
- -- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible
- category.ID = categoryName
- end
- group:SetName(category.ID)
- BlizOptionsIDMap[categoryName] = category.ID
- Settings.RegisterAddOnCategory(category)
- end
- else
- group:SetName(name or appName, parent)
- InterfaceOptions_AddCategory(group.frame)
- end
-
- return group.frame, group.frame.name
+ InterfaceOptions_AddCategory(group.frame)
+ return group.frame
else
error(("%s has already been added to the Blizzard Options Window with the given path"):format(appName), 2)
end
diff --git a/Decursive/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua b/Decursive/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
index 72e9c60..d98c020 100644
--- a/Decursive/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
+++ b/Decursive/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
@@ -4,20 +4,20 @@
-- * Valid **uiTypes**: "cmd", "dropdown", "dialog". This is verified by the library at call time. \\
-- * The **uiName** field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.\\
-- * The **appName** field is the options table name as given at registration time \\
---
+--
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
-- @class file
-- @name AceConfigRegistry-3.0
--- @release $Id$
-local CallbackHandler = LibStub("CallbackHandler-1.0")
-
-local MAJOR, MINOR = "AceConfigRegistry-3.0", 22
+-- @release $Id: AceConfigRegistry-3.0.lua 921 2010-05-09 15:49:14Z nevcairiel $
+local MAJOR, MINOR = "AceConfigRegistry-3.0", 12
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigRegistry then return end
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
+local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+
if not AceConfigRegistry.callbacks then
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
end
@@ -33,7 +33,7 @@ local error, assert = error, assert
AceConfigRegistry.validated = {
- -- list of options table names ran through :ValidateOptionsTable automatically.
+ -- list of options table names ran through :ValidateOptionsTable automatically.
-- CLEARED ON PURPOSE, since newer versions may have newer validators
cmd = {},
dropdown = {},
@@ -57,8 +57,8 @@ local istable={["table"]=true, _="table"}
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
local optstring={["nil"]=true,["string"]=true, _="string"}
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
-local optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"}
+local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
@@ -66,7 +66,6 @@ local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=
local opttable={["nil"]=true,["table"]=true, _="table"}
local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
-local optstringnumber={["nil"]=true,["string"]=true,["number"]=true, _="string or number"}
local basekeys={
type=isstring,
@@ -83,33 +82,24 @@ local basekeys={
dialogHidden=optmethodbool,
dropdownHidden=optmethodbool,
cmdHidden=optmethodbool,
- tooltipHyperlink=optstringfunc,
- icon=optstringnumberfunc,
+ icon=optstringfunc,
iconCoords=optmethodtable,
handler=opttable,
get=optmethodfalse,
set=optmethodfalse,
func=optmethodfalse,
arg={["*"]=true},
- width=optstringnumber,
- relWidth=optnumber,
+ width=optstring,
}
local typedkeys={
- header={
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
- },
+ header={},
description={
- image=optstringnumberfunc,
+ image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
fontSize=optstringfunc,
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
},
group={
args=istable,
@@ -122,13 +112,10 @@ local typedkeys={
childGroups=optstring,
},
execute={
- image=optstringnumberfunc,
+ image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
},
input={
pattern=optstring,
@@ -140,11 +127,8 @@ local typedkeys={
},
toggle={
tristate=optbool,
- image=optstringnumberfunc,
+ image=optstringfunc,
imageCoords=optmethodtable,
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
},
tristate={
},
@@ -156,22 +140,17 @@ local typedkeys={
step=optnumber,
bigStep=optnumber,
isPercent=optbool,
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
},
select={
values=ismethodtable,
- sorting=optmethodtable,
style={
- ["nil"]=true,
- ["string"]={dropdown=true,radio=true},
+ ["nil"]=true,
+ ["string"]={dropdown=true,radio=true},
_="string: 'dropdown' or 'radio'"
},
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
- itemControl=optstring,
},
multiselect={
values=ismethodtable,
@@ -182,15 +161,10 @@ local typedkeys={
dropdownControl=optstring,
},
color={
- hasAlpha=optmethodbool,
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
+ hasAlpha=optbool,
},
keybinding={
- control=optstring,
- dialogControl=optstring,
- dropdownControl=optstring,
+ -- TODO
},
}
@@ -227,13 +201,13 @@ local function validate(options,errlvl,...)
if type(options.type)~="string" then
err(".type: expected a string, got a "..type(options.type), errlvl,...)
end
-
+
-- get type and 'typedkeys' member
local tk = typedkeys[options.type]
if not tk then
err(".type: unknown type '"..options.type.."'", errlvl,...)
end
-
+
-- make sure that all options[] are known parameters
for k,v in pairs(options) do
if not (tk[k] or basekeys[k]) then
@@ -313,8 +287,7 @@ end
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param options The options table, OR a function reference that generates it on demand. \\
-- See the top of the page for info on arguments passed to such functions.
--- @param skipValidation Skip options table validation (primarily useful for extremely huge options, with a noticeable slowdown)
-function AceConfigRegistry:RegisterOptionsTable(appName, options, skipValidation)
+function AceConfigRegistry:RegisterOptionsTable(appName, options)
if type(options)=="table" then
if options.type~="group" then -- quick sanity checker
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
@@ -322,18 +295,18 @@ function AceConfigRegistry:RegisterOptionsTable(appName, options, skipValidation
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
- if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
+ if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
- return options
+ return options
end
elseif type(options)=="function" then
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
local tab = assert(options(uiType, uiName, appName))
- if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
+ if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
@@ -364,7 +337,7 @@ function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
if not f then
return nil
end
-
+
if uiType then
return f(uiType,uiName,1) -- get the table for us
else
diff --git a/Decursive/Libs/AceConsole-3.0/AceConsole-3.0.lua b/Decursive/Libs/AceConsole-3.0/AceConsole-3.0.lua
index 8e5ec81..c001123 100644
--- a/Decursive/Libs/AceConsole-3.0/AceConsole-3.0.lua
+++ b/Decursive/Libs/AceConsole-3.0/AceConsole-3.0.lua
@@ -2,14 +2,14 @@
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs.
--
--- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
+-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole.
-- @class file
-- @name AceConsole-3.0
--- @release $Id$
+-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $
local MAJOR,MINOR = "AceConsole-3.0", 7
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
@@ -29,6 +29,10 @@ local max = math.max
-- WoW APIs
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
+
local tmp={}
local function Print(self,frame,...)
local n=0
@@ -80,11 +84,11 @@ end
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
-
+
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
-
+
local name = "ACECONSOLE_"..command:upper()
-
+
if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
self[func](self, input, editBox)
@@ -128,11 +132,11 @@ local function nils(n, ...)
return ...
end
end
+
-
---- Retreive one or more space-separated arguments from a string.
+--- Retreive one or more space-separated arguments from a string.
-- Treats quoted strings and itemlinks as non-spaced.
--- @param str The raw argument string
+-- @param string The raw argument string
-- @param numargs How many arguments to get (default 1)
-- @param startpos Where in the string to start scanning (default 1)
-- @return Returns arg1, arg2, ..., nextposition\\
@@ -140,7 +144,7 @@ end
function AceConsole:GetArgs(str, numargs, startpos)
numargs = numargs or 1
startpos = max(startpos or 1, 1)
-
+
local pos=startpos
-- find start of new arg
@@ -165,24 +169,24 @@ function AceConsole:GetArgs(str, numargs, startpos)
else
delim_or_pipe="([| ])"
end
-
+
startpos = pos
-
+
while true do
-- find delimiter or hyperlink
- local _
+ local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos)
-
+
if not pos then break end
-
+
if ch=="|" then
-- some kind of escape
-
+
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h
pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
-
+
pos=strfind(str, "|h", pos+2) -- second |h
if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then
@@ -190,16 +194,16 @@ function AceConsole:GetArgs(str, numargs, startpos)
pos=strfind(str, "|t", pos+2)
if not pos then break end
end
-
+
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
-
+
else
-- found delimiter, done with this arg
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
-
+
end
-
+
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
return strsub(str, startpos), nils(numargs-1, 1e9)
end
@@ -210,10 +214,10 @@ end
local mixins = {
"Print",
"Printf",
- "RegisterChatCommand",
+ "RegisterChatCommand",
"UnregisterChatCommand",
"GetArgs",
-}
+}
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
diff --git a/Decursive/Libs/AceDB-3.0/AceDB-3.0.lua b/Decursive/Libs/AceDB-3.0/AceDB-3.0.lua
index f83a715..7a29450 100644
--- a/Decursive/Libs/AceDB-3.0/AceDB-3.0.lua
+++ b/Decursive/Libs/AceDB-3.0/AceDB-3.0.lua
@@ -10,7 +10,6 @@
-- * **race** Race-specific data. All of the players characters of the same race share this database.
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
--- * **locale** Locale specific data, based on the locale of the players game client.
-- * **global** Global Data. All characters on the same account share this database.
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
--
@@ -40,19 +39,23 @@
-- end
-- @class file
-- @name AceDB-3.0.lua
--- @release $Id$
-local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 33
-local AceDB = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
+-- @release $Id: AceDB-3.0.lua 940 2010-06-19 08:01:47Z nevcairiel $
+local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 21
+local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
if not AceDB then return end -- No upgrade needed
-- Lua APIs
local type, pairs, next, error = type, pairs, next, error
-local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
-- WoW APIs
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: LibStub
+
AceDB.db_registry = AceDB.db_registry or {}
AceDB.frame = AceDB.frame or CreateFrame("Frame")
@@ -94,11 +97,11 @@ local function copyDefaults(dest, src)
-- This is a metatable used for table defaults
local mt = {
-- This handles the lookup and creation of new subtables
- __index = function(t,k2)
- if k2 == nil then return nil end
+ __index = function(t,k)
+ if k == nil then return nil end
local tbl = {}
copyDefaults(tbl, v)
- rawset(t, k2, tbl)
+ rawset(t, k, tbl)
return tbl
end,
}
@@ -111,15 +114,7 @@ local function copyDefaults(dest, src)
end
else
-- Values are not tables, so this is just a simple return
- -- (PR #10 backport: the old `k2~=nil and v or nil` short-circuits to
- -- nil whenever the default `v` itself is falsy — so `["*"] = false`
- -- defaults silently became nil. Make the read explicit instead.)
- local mt = {
- __index = function(t,k2)
- if k2 == nil then return nil end
- return v
- end,
- }
+ local mt = {__index = function(t,k) return k~=nil and v or nil end}
setmetatable(dest, mt)
end
elseif type(v) == "table" then
@@ -265,12 +260,6 @@ local _, classKey = UnitClass("player")
local _, raceKey = UnitRace("player")
local factionKey = UnitFactionGroup("player")
local factionrealmKey = factionKey .. " - " .. realmKey
-local localeKey = GetLocale():lower()
-
-local regionTable = { "US", "KR", "EU", "TW", "CN" }
-local regionKey = regionTable[GetCurrentRegion()] or GetCurrentRegionName() or "TR"
-local factionrealmregionKey = factionrealmKey .. " - " .. regionKey
-
-- Actual database initialization function
local function initdb(sv, defaults, defaultProfile, olddb, parent)
-- Generate the database keys for each section
@@ -306,9 +295,7 @@ local function initdb(sv, defaults, defaultProfile, olddb, parent)
["race"] = raceKey,
["faction"] = factionKey,
["factionrealm"] = factionrealmKey,
- ["factionrealmregion"] = factionrealmregionKey,
["profile"] = profileKey,
- ["locale"] = localeKey,
["global"] = true,
["profiles"] = true,
}
@@ -365,10 +352,10 @@ local function logoutHandler(frame, event)
for db in pairs(AceDB.db_registry) do
db.callbacks:Fire("OnDatabaseShutdown", db)
db:RegisterDefaults(nil)
-
+
-- cleanup sections that are empty without defaults
local sv = rawget(db, "sv")
- for section in pairs(rawget(db, "keys")) do
+ for section in pairs(db.keys) do
if rawget(sv, section) then
-- global is special, all other sections have sub-entrys
-- also don't delete empty profiles on main dbs, only on namespaces
@@ -385,26 +372,6 @@ local function logoutHandler(frame, event)
end
end
end
-
- -- second pass after everything else is cleaned up to remove empty namespaces
- -- can't be run in-loop above since there is no guaranteed order
- for db in pairs(AceDB.db_registry) do
- local sv = rawget(db, "sv")
- local namespaces = rawget(sv, "namespaces")
- if namespaces then
- for name in pairs(namespaces) do
- -- cleanout empty profiles table, if still present
- if namespaces[name].profiles and not next(namespaces[name].profiles) then
- namespaces[name].profiles = nil
- end
-
- -- remove entire namespace, if needed
- if not next(namespaces[name]) then
- namespaces[name] = nil
- end
- end
- end
- end
end
end
@@ -421,7 +388,7 @@ AceDB.frame:SetScript("OnEvent", logoutHandler)
-- @param defaults A table of defaults for this database
function DBObjectLib:RegisterDefaults(defaults)
if defaults and type(defaults) ~= "table" then
- error(("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
+ error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
end
validateDefaults(defaults, self.keys)
@@ -453,7 +420,7 @@ end
-- @param name The name of the profile to set as the current profile
function DBObjectLib:SetProfile(name)
if type(name) ~= "string" then
- error(("Usage: AceDBObject:SetProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
end
-- changing to the same profile, dont do anything
@@ -495,7 +462,7 @@ end
-- @param tbl A table to store the profile names in (optional)
function DBObjectLib:GetProfiles(tbl)
if tbl and type(tbl) ~= "table" then
- error(("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected, got %q."):format(type(tbl)), 2)
+ error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
end
-- Clear the container table
@@ -533,15 +500,15 @@ end
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:DeleteProfile(name, silent)
if type(name) ~= "string" then
- error(("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
end
if self.keys.profile == name then
- error(("Cannot delete the active profile (%q) in an AceDBObject."):format(name), 2)
+ error("Cannot delete the active profile in an AceDBObject.", 2)
end
if not rawget(self.profiles, name) and not silent then
- error(("Cannot delete profile %q as it does not exist."):format(name), 2)
+ error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
end
self.profiles[name] = nil
@@ -553,26 +520,6 @@ function DBObjectLib:DeleteProfile(name, silent)
end
end
- -- remove from unloaded namespaces
- if self.sv.namespaces then
- for nsname, data in pairs(self.sv.namespaces) do
- if self.children and self.children[nsname] then
- -- already a mapped namespace
- elseif data.profiles then
- data.profiles[name] = nil
- end
- end
- end
-
- -- switch all characters that use this profile back to the default
- if self.sv.profileKeys then
- for key, profile in pairs(self.sv.profileKeys) do
- if profile == name then
- self.sv.profileKeys[key] = nil
- end
- end
- end
-
-- Callback: OnProfileDeleted, database, profileKey
self.callbacks:Fire("OnProfileDeleted", self, name)
end
@@ -583,15 +530,15 @@ end
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:CopyProfile(name, silent)
if type(name) ~= "string" then
- error(("Usage: AceDBObject:CopyProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
end
if name == self.keys.profile then
- error(("Cannot have the same source and destination profiles (%q)."):format(name), 2)
+ error("Cannot have the same source and destination profiles.", 2)
end
if not rawget(self.profiles, name) and not silent then
- error(("Cannot copy profile %q as it does not exist."):format(name), 2)
+ error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
end
-- Reset the profile before copying
@@ -609,20 +556,6 @@ function DBObjectLib:CopyProfile(name, silent)
end
end
- -- copy unloaded namespaces
- if self.sv.namespaces then
- for nsname, data in pairs(self.sv.namespaces) do
- if self.children and self.children[nsname] then
- -- already a mapped namespace
- elseif data.profiles then
- -- reset the current profile
- data.profiles[self.keys.profile] = {}
- -- copy data
- copyTable(data.profiles[name], data.profiles[self.keys.profile])
- end
- end
- end
-
-- Callback: OnProfileCopied, database, sourceProfileKey
self.callbacks:Fire("OnProfileCopied", self, name)
end
@@ -649,18 +582,6 @@ function DBObjectLib:ResetProfile(noChildren, noCallbacks)
end
end
- -- reset unloaded namespaces
- if self.sv.namespaces and not noChildren then
- for nsname, data in pairs(self.sv.namespaces) do
- if self.children and self.children[nsname] then
- -- already a mapped namespace
- elseif data.profiles then
- -- reset the current profile
- data.profiles[self.keys.profile] = nil
- end
- end
- end
-
-- Callback: OnProfileReset, database
if not noCallbacks then
self.callbacks:Fire("OnProfileReset", self)
@@ -671,8 +592,8 @@ end
-- profile.
-- @param defaultProfile The profile name to use as the default
function DBObjectLib:ResetDB(defaultProfile)
- if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
- error(("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or true expected, got %q."):format(type(defaultProfile)), 2)
+ if defaultProfile and type(defaultProfile) ~= "string" then
+ error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
end
local sv = self.sv
@@ -680,6 +601,8 @@ function DBObjectLib:ResetDB(defaultProfile)
sv[k] = nil
end
+ local parent = self.parent
+
initdb(sv, self.defaults, defaultProfile, self)
-- fix the child namespaces
@@ -706,13 +629,13 @@ end
-- @param defaults A table of values to use as defaults
function DBObjectLib:RegisterNamespace(name, defaults)
if type(name) ~= "string" then
- error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected, got %q."):format(type(name)), 2)
+ error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
end
if defaults and type(defaults) ~= "table" then
- error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
+ error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
end
if self.children and self.children[name] then
- error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace called %q already exists."):format(name), 2)
+ error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
end
local sv = self.sv
@@ -736,10 +659,10 @@ end
-- @return the namespace object if found
function DBObjectLib:GetNamespace(name, silent)
if type(name) ~= "string" then
- error(("Usage: AceDBObject:GetNamespace(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
end
if not silent and not (self.children and self.children[name]) then
- error(("Usage: AceDBObject:GetNamespace(name): 'name' - namespace %q does not exist."):format(name), 2)
+ error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
end
if not self.children then self.children = {} end
return self.children[name]
@@ -778,15 +701,15 @@ function AceDB:New(tbl, defaults, defaultProfile)
end
if type(tbl) ~= "table" then
- error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected, got %q."):format(type(tbl)), 2)
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
end
if defaults and type(defaults) ~= "table" then
- error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected, got %q."):format(type(defaults)), 2)
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
end
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
- error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected, got %q."):format(type(defaultProfile)), 2)
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
end
return initdb(tbl, defaults, defaultProfile)
diff --git a/Decursive/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua b/Decursive/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
index b91082b..bc56106 100644
--- a/Decursive/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
+++ b/Decursive/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
@@ -1,9 +1,9 @@
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file
-- @name AceDBOptions-3.0
--- @release $Id$
-local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
-local AceDBOptions = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
+-- @release $Id: AceDBOptions-3.0.lua 938 2010-06-13 07:21:38Z nevcairiel $
+local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 12
+local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
if not AceDBOptions then return end -- No upgrade needed
@@ -13,6 +13,10 @@ local pairs, next = pairs, next
-- WoW APIs
local UnitClass = UnitClass
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE
+
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
AceDBOptions.handlers = AceDBOptions.handlers or {}
@@ -21,208 +25,168 @@ AceDBOptions.handlers = AceDBOptions.handlers or {}
]]
local L = {
- choose = "Existing Profiles",
- choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
- choose_sub = "Select one of your currently available profiles.",
- copy = "Copy From",
- copy_desc = "Copy the settings from one existing profile into the currently active profile.",
- current = "Current Profile:",
default = "Default",
- delete = "Delete a Profile",
- delete_confirm = "Are you sure you want to delete the selected profile?",
- delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
- delete_sub = "Deletes a profile from the database.",
intro = "You can change the active database profile, so you can have different settings for every character.",
+ reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
+ reset = "Reset Profile",
+ reset_sub = "Reset the current profile to the default",
+ choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
new = "New",
new_sub = "Create a new empty profile.",
+ choose = "Existing Profiles",
+ choose_sub = "Select one of your currently available profiles.",
+ copy_desc = "Copy the settings from one existing profile into the currently active profile.",
+ copy = "Copy From",
+ delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
+ delete = "Delete a Profile",
+ delete_sub = "Deletes a profile from the database.",
+ delete_confirm = "Are you sure you want to delete the selected profile?",
profiles = "Profiles",
profiles_sub = "Manage Profiles",
- reset = "Reset Profile",
- reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
- reset_sub = "Reset the current profile to the default",
+ current = "Current Profile:",
}
local LOCALE = GetLocale()
if LOCALE == "deDE" then
- L["choose"] = "Vorhandene Profile"
- L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder wähle eines der vorhandenen Profile aus."
- L["choose_sub"] = "Wählt ein bereits vorhandenes Profil aus."
- L["copy"] = "Kopieren von..."
- L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
- L["current"] = "Aktuelles Profil:"
L["default"] = "Standard"
- L["delete"] = "Profil löschen"
- L["delete_confirm"] = "Willst du das ausgewählte Profil wirklich löschen?"
- L["delete_desc"] = "Lösche vorhandene oder unbenutzte Profile aus der Datenbank, um Platz zu sparen und die SavedVariables-Datei 'sauber' zu halten."
- L["delete_sub"] = "Löscht ein Profil aus der Datenbank."
- L["intro"] = "Hier kannst du das aktive Datenbankprofil ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird."
+ L["intro"] = "Hier kannst du das aktive Datenbankprofile \195\164ndern, damit du verschiedene Einstellungen f\195\188r jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration m\195\182glich wird."
+ L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zur\195\188ck, f\195\188r den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
+ L["reset"] = "Profil zur\195\188cksetzen"
+ L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen."
+ L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder w\195\164hle eines der vorhandenen Profile aus."
L["new"] = "Neu"
L["new_sub"] = "Ein neues Profil erstellen."
+ L["choose"] = "Vorhandene Profile"
+ L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus."
+ L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
+ L["copy"] = "Kopieren von..."
+ L["delete_desc"] = "L\195\182sche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
+ L["delete"] = "Profil l\195\182schen"
+ L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank."
+ L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?"
L["profiles"] = "Profile"
L["profiles_sub"] = "Profile verwalten"
- L["reset"] = "Profil zurücksetzen"
- L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zurück, für den Fall, dass mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
- L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen."
+ --L["current"] = "Current Profile:"
elseif LOCALE == "frFR" then
- L["choose"] = "Profils existants"
- L["choose_desc"] = "Vous pouvez créer un nouveau profil en entrant un nouveau nom dans la boîte de saisie, ou en choississant un des profils déjà existants."
- L["choose_sub"] = "Permet de choisir un des profils déjà disponibles."
- L["copy"] = "Copier à partir de"
- L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif."
- L["current"] = "Profil actuel :"
- L["default"] = "Défaut"
- L["delete"] = "Supprimer un profil"
- L["delete_confirm"] = "Etes-vous sûr de vouloir supprimer le profil sélectionné ?"
- L["delete_desc"] = "Supprime les profils existants inutilisés de la base de données afin de gagner de la place et de nettoyer le fichier SavedVariables."
- L["delete_sub"] = "Supprime un profil de la base de données."
- L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des paramètres différents pour chaque personnage, permettant ainsi d'avoir une configuration très flexible."
+ L["default"] = "D\195\169faut"
+ L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des param\195\168tres diff\195\169rents pour chaque personnage, permettant ainsi d'avoir une configuration tr\195\168s flexible."
+ L["reset_desc"] = "R\195\169initialise le profil actuel au cas o\195\185 votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
+ L["reset"] = "R\195\169initialiser le profil"
+ L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut."
+ L["choose_desc"] = "Vous pouvez cr\195\169er un nouveau profil en entrant un nouveau nom dans la bo\195\174te de saisie, ou en choississant un des profils d\195\169j\195\160 existants."
L["new"] = "Nouveau"
- L["new_sub"] = "Créée un nouveau profil vierge."
+ L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge."
+ L["choose"] = "Profils existants"
+ L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles."
+ L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif."
+ L["copy"] = "Copier \195\160 partir de"
+ L["delete_desc"] = "Supprime les profils existants inutilis\195\169s de la base de donn\195\169es afin de gagner de la place et de nettoyer le fichier SavedVariables."
+ L["delete"] = "Supprimer un profil"
+ L["delete_sub"] = "Supprime un profil de la base de donn\195\169es."
+ L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?"
L["profiles"] = "Profils"
L["profiles_sub"] = "Gestion des profils"
- L["reset"] = "Réinitialiser le profil"
- L["reset_desc"] = "Réinitialise le profil actuel au cas où votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
- L["reset_sub"] = "Réinitialise le profil actuel avec les paramètres par défaut."
+ --L["current"] = "Current Profile:"
elseif LOCALE == "koKR" then
- L["choose"] = "기존 프로필"
- L["choose_desc"] = "편집 상자에 이름을 입력하여 새로운 프로필을 만들거나 이미 존재하는 프로필 중 하나를 선택할 수 있습니다."
- L["choose_sub"] = "현재 이용할 수 있는 프로필 중 하나를 선택합니다."
- L["copy"] = "복사해 올 프로필"
- L["copy_desc"] = "기존 프로필의 설정을 현재 활성화된 프로필로 복사합니다."
- L["current"] = "현재 프로필:"
L["default"] = "기본값"
- L["delete"] = "프로필 삭제"
- L["delete_confirm"] = "선택한 프로필을 삭제하시겠습니까?"
- L["delete_desc"] = "데이터베이스에서 기존 프로필과 사용하지 않는 프로필을 삭제하여 공간을 절약하고 SavedVariables 파일을 정리합니다."
- L["delete_sub"] = "데이터베이스에서 프로필을 삭제합니다."
- L["intro"] = "활성 데이터베이스 프로필을 변경할 수 있으며, 모든 캐릭터마다 서로 다른 설정을 지정할 수 있습니다."
+ L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
+ L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
+ L["reset"] = "프로필 초기화"
+ L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
+ L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
L["new"] = "새로운 프로필"
- L["new_sub"] = "비어 있는 프로필을 새로 만듭니다."
+ L["new_sub"] = "새로운 프로필을 만듭니다."
+ L["choose"] = "프로필 선택"
+ L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
+ L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
+ L["copy"] = "복사"
+ L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
+ L["delete"] = "프로필 삭제"
+ L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
+ L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
L["profiles"] = "프로필"
- L["profiles_sub"] = "프로필 관리"
- L["reset"] = "프로필 재설정"
- L["reset_desc"] = "구성이 손상되었거나 처음부터 다시 시작하고 싶은 경우 현재 프로필을 기본값으로 재설정하세요."
- L["reset_sub"] = "현재 프로필을 기본값으로 재설정합니다"
+ L["profiles_sub"] = "프로필 설정"
+ --L["current"] = "Current Profile:"
elseif LOCALE == "esES" or LOCALE == "esMX" then
- L["choose"] = "Perfiles existentes"
- L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
- L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
- L["copy"] = "Copiar de"
- L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
- L["current"] = "Perfil actual:"
L["default"] = "Por defecto"
- L["delete"] = "Borrar un Perfil"
- L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
- L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
- L["delete_sub"] = "Borra un perfil de la base de datos."
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
+ L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
+ L["reset"] = "Reiniciar Perfil"
+ L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
+ L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
L["new"] = "Nuevo"
L["new_sub"] = "Crear un nuevo perfil vacio."
+ L["choose"] = "Perfiles existentes"
+ L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
+ L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
+ L["copy"] = "Copiar de"
+ L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
+ L["delete"] = "Borrar un Perfil"
+ L["delete_sub"] = "Borra un perfil de la base de datos."
+ L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
L["profiles"] = "Perfiles"
L["profiles_sub"] = "Manejar Perfiles"
- L["reset"] = "Reiniciar Perfil"
- L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
- L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
+ --L["current"] = "Current Profile:"
elseif LOCALE == "zhTW" then
- L["choose"] = "現有的設定檔"
- L["choose_desc"] = "您可以在文字方塊內輸入名字以建立新的設定檔,或是選擇一個現有的設定檔使用。"
- L["choose_sub"] = "從當前可用的設定檔裡面選擇一個。"
- L["copy"] = "複製自"
- L["copy_desc"] = "從一個現有的設定檔,將設定複製到現在使用中的設定檔。"
- L["current"] = "目前設定檔:"
L["default"] = "預設"
- L["delete"] = "刪除一個設定檔"
- L["delete_confirm"] = "確定要刪除所選擇的設定檔嗎?"
- L["delete_desc"] = "從資料庫裡刪除不再使用的設定檔,以節省空間,並且清理 SavedVariables 檔案。"
- L["delete_sub"] = "從資料庫裡刪除一個設定檔。"
- L["intro"] = "您可以從資料庫中選擇一個設定檔來使用,如此就可以讓每個角色使用不同的設定。"
+ L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
+ L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
+ L["reset"] = "重置設定檔"
+ L["reset_sub"] = "將當前的設定檔恢復為預設值"
+ L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
L["new"] = "新建"
L["new_sub"] = "新建一個空的設定檔。"
+ L["choose"] = "現有的設定檔"
+ L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
+ L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
+ L["copy"] = "複製自"
+ L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
+ L["delete"] = "刪除一個設定檔"
+ L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
+ L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
L["profiles"] = "設定檔"
L["profiles_sub"] = "管理設定檔"
- L["reset"] = "重置設定檔"
- L["reset_desc"] = "將現用的設定檔重置為預設值;用於設定檔損壞,或者單純想要重來的情況。"
- L["reset_sub"] = "將目前的設定檔重置為預設值"
+ --L["current"] = "Current Profile:"
elseif LOCALE == "zhCN" then
- L["choose"] = "现有的配置文件"
- L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
- L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
- L["copy"] = "复制自"
- L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
- L["current"] = "当前配置文件:"
L["default"] = "默认"
- L["delete"] = "删除一个配置文件"
- L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
- L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
- L["delete_sub"] = "从数据库里删除一个配置文件。"
- L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
+ L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
+ L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
+ L["reset"] = "重置配置文件"
+ L["reset_sub"] = "将当前的配置文件恢复为默认值"
+ L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
L["new"] = "新建"
L["new_sub"] = "新建一个空的配置文件。"
+ L["choose"] = "现有的配置文件"
+ L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
+ L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
+ L["copy"] = "复制自"
+ L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
+ L["delete"] = "删除一个配置文件"
+ L["delete_sub"] = "从数据库里删除一个配置文件。"
+ L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
L["profiles"] = "配置文件"
L["profiles_sub"] = "管理配置文件"
- L["reset"] = "重置配置文件"
- L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
- L["reset_sub"] = "将当前的配置文件恢复为默认值"
+ --L["current"] = "Current Profile:"
elseif LOCALE == "ruRU" then
- L["choose"] = "Существующие профили"
- L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
- L["choose_sub"] = "Выбор одного из уже доступных профилей."
- L["copy"] = "Скопировать из"
- L["copy_desc"] = "Копирование настроек из выбранного профиля в активный."
- L["current"] = "Текущий профиль:"
L["default"] = "По умолчанию"
- L["delete"] = "Удалить профиль"
- L["delete_confirm"] = "Вы уверены, что хотите удалить выбранный профиль?"
- L["delete_desc"] = "Удаление существующего и неиспользуемого профиля из базы данных для сохранения места, и очистка файла SavedVariables."
- L["delete_sub"] = "Удаление профиля из базы данных."
- L["intro"] = "Изменяя активный профиль, Вы можете задать разные настройки для каждого персонажа."
+ L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
+ L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
+ L["reset"] = "Сброс профиля"
+ L["reset_sub"] = "Сброс текущего профиля на стандартный"
+ L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
L["new"] = "Новый"
- L["new_sub"] = "Создание нового чистого профиля."
+ L["new_sub"] = "Создать новый чистый профиль"
+ L["choose"] = "Существующие профили"
+ L["choose_sub"] = "Выбор одиного из уже доступных профилей"
+ L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
+ L["copy"] = "Скопировать из"
+ L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
+ L["delete"] = "Удалить профиль"
+ L["delete_sub"] = "Удаление профиля из БД"
+ L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
L["profiles"] = "Профили"
L["profiles_sub"] = "Управление профилями"
- L["reset"] = "Сбросить профиль"
- L["reset_desc"] = "Сброс текущего профиля к стандартным настройкам, если Ваша конфигурация испорчена или Вы хотите настроить все заново."
- L["reset_sub"] = "Сброс текущего профиля на стандартный"
-elseif LOCALE == "itIT" then
- L["choose"] = "Profili Esistenti"
- L["choose_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili già esistenti."
- L["choose_sub"] = "Seleziona uno dei profili attualmente disponibili."
- L["copy"] = "Copia Da"
- L["copy_desc"] = "Copia le impostazioni da un profilo esistente nel profilo attivo in questo momento."
- L["current"] = "Profilo Attivo:"
- L["default"] = "Predefinito"
- L["delete"] = "Cancella un Profilo"
- L["delete_confirm"] = "Sei sicuro di voler cancellare il profilo selezionato?"
- L["delete_desc"] = "Cancella i profili non utilizzati dal database per risparmiare spazio e mantenere puliti i file di configurazione SavedVariables."
- L["delete_sub"] = "Cancella un profilo dal Database."
- L["intro"] = "Puoi cambiare il profilo attivo, in modo da usare impostazioni diverse per ogni personaggio."
- L["new"] = "Nuovo"
- L["new_sub"] = "Crea un nuovo profilo vuoto."
- L["profiles"] = "Profili"
- L["profiles_sub"] = "Gestisci Profili"
- L["reset"] = "Reimposta Profilo"
- L["reset_desc"] = "Riporta il tuo profilo attivo alle sue impostazioni predefinite, nel caso in cui la tua configurazione si sia corrotta, o semplicemente tu voglia re-inizializzarla."
- L["reset_sub"] = "Reimposta il profilo ai suoi valori predefiniti."
-elseif LOCALE == "ptBR" then
- L["choose"] = "Perfis Existentes"
- L["choose_desc"] = "Você pode tanto criar um perfil novo tanto digitando um nome na caixa de texto, quanto escolher um dos perfis já existentes."
- L["choose_sub"] = "Selecione um de seus perfis atualmente disponíveis."
- L["copy"] = "Copiar De"
- L["copy_desc"] = "Copia as definições de um perfil existente no perfil atualmente ativo."
- L["current"] = "Perfil Autal:"
- L["default"] = "Padrão"
- L["delete"] = "Remover um Perfil"
- L["delete_confirm"] = "Tem certeza que deseja remover o perfil selecionado?"
- L["delete_desc"] = "Remove perfis existentes e inutilizados do banco de dados para economizar espaço, e limpar o arquivo SavedVariables."
- L["delete_sub"] = "Remove um perfil do banco de dados."
- L["intro"] = "Você pode alterar o perfil do banco de dados ativo, para que possa ter definições diferentes para cada personagem."
- L["new"] = "Novo"
- L["new_sub"] = "Cria um novo perfil vazio."
- L["profiles"] = "Perfis"
- L["profiles_sub"] = "Gerenciar Perfis"
- L["reset"] = "Resetar Perfil"
- L["reset_desc"] = "Reseta o perfil atual para os valores padrões, no caso de sua configuração estar quebrada, ou simplesmente se deseja começar novamente."
- L["reset_sub"] = "Resetar o perfil atual ao padrão"
+ --L["current"] = "Current Profile:"
end
local defaultProfiles
@@ -236,22 +200,22 @@ local tmpprofiles = {}
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
local function getProfileList(db, common, nocurrent)
local profiles = {}
-
+
-- copy existing profiles into the table
local currentProfile = db:GetCurrentProfile()
- for i,v in pairs(db:GetProfiles(tmpprofiles)) do
- if not (nocurrent and v == currentProfile) then
- profiles[v] = v
- end
+ for i,v in pairs(db:GetProfiles(tmpprofiles)) do
+ if not (nocurrent and v == currentProfile) then
+ profiles[v] = v
+ end
end
-
+
-- add our default profiles to choose from ( or rename existing profiles)
for k,v in pairs(defaultProfiles) do
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
profiles[k] = v
end
end
-
+
return profiles
end
@@ -276,11 +240,11 @@ function OptionsHandlerPrototype:GetCurrentProfile()
return self.db:GetCurrentProfile()
end
---[[
+--[[
List all active profiles
you can control the output with the .arg variable
currently four modes are supported
-
+
(empty) - return all available profiles
"nocurrent" - returns all available profiles except the currently active profile
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
@@ -298,7 +262,7 @@ function OptionsHandlerPrototype:ListProfiles(info)
else
profiles = getProfileList(self.db)
end
-
+
return profiles
end
@@ -332,19 +296,19 @@ local function getOptionsHandler(db, noDefaultProfiles)
if not defaultProfiles then
generateDefaultProfiles(db)
end
-
+
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
-
+
for k,v in pairs(OptionsHandlerPrototype) do
handler[k] = v
end
-
+
AceDBOptions.handlers[db] = handler
return handler
end
--[[
- the real options table
+ the real options table
]]
local optionsTable = {
desc = {
@@ -432,7 +396,7 @@ local optionsTable = {
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
-- @param db The database object to create the options table for.
-- @return The options table to be used in AceConfig-3.0
--- @usage
+-- @usage
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
@@ -441,7 +405,7 @@ function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
name = L["profiles"],
desc = L["profiles_sub"],
}
-
+
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
tbl.args = optionsTable
diff --git a/Decursive/Libs/AceEvent-3.0/AceEvent-3.0.lua b/Decursive/Libs/AceEvent-3.0/AceEvent-3.0.lua
index 9f96bf3..e9b18b1 100644
--- a/Decursive/Libs/AceEvent-3.0/AceEvent-3.0.lua
+++ b/Decursive/Libs/AceEvent-3.0/AceEvent-3.0.lua
@@ -2,17 +2,15 @@
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
--
--- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
+-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent.
-- @class file
-- @name AceEvent-3.0
--- @release $Id$
-local CallbackHandler = LibStub("CallbackHandler-1.0")
-
-local MAJOR, MINOR = "AceEvent-3.0", 4
+-- @release $Id: AceEvent-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
+local MAJOR, MINOR = "AceEvent-3.0", 3
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
if not AceEvent then return end
@@ -20,27 +18,29 @@ if not AceEvent then return end
-- Lua APIs
local pairs = pairs
+local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
-- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then
- AceEvent.events = CallbackHandler:New(AceEvent,
+ AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end
-function AceEvent.events:OnUsed(target, eventname)
+function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname)
end
-function AceEvent.events:OnUnused(target, eventname)
+function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname)
end
-- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then
- AceEvent.messages = CallbackHandler:New(AceEvent,
+ AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
)
AceEvent.SendMessage = AceEvent.messages.Fire
@@ -55,7 +55,7 @@ local mixins = {
}
--- Register for a Blizzard Event.
--- 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)
+-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent
-- @class function
@@ -71,7 +71,7 @@ local mixins = {
-- @param event The event to unregister
--- Register for a custom AceEvent-internal message.
--- 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)
+-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage
-- @class function
diff --git a/Decursive/Libs/AceGUI-3.0/AceGUI-3.0.lua b/Decursive/Libs/AceGUI-3.0/AceGUI-3.0.lua
index 35b176e..53295bb 100644
--- a/Decursive/Libs/AceGUI-3.0/AceGUI-3.0.lua
+++ b/Decursive/Libs/AceGUI-3.0/AceGUI-3.0.lua
@@ -1,6 +1,6 @@
--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs.
-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself
--- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
+-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
-- stand-alone distribution.
--
-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly,
@@ -24,29 +24,34 @@
-- f:AddChild(btn)
-- @class file
-- @name AceGUI-3.0
--- @release $Id$
-local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 41
+-- @release $Id: AceGUI-3.0.lua 924 2010-05-13 15:12:20Z nevcairiel $
+local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 33
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
if not AceGUI then return end -- No upgrade needed
-- Lua APIs
-local tinsert, wipe = table.insert, table.wipe
+local tconcat, tremove, tinsert = table.concat, table.remove, table.insert
local select, pairs, next, type = select, pairs, next, type
-local error, assert = error, assert
-local setmetatable, rawget = setmetatable, rawget
-local math_max, math_min, math_ceil = math.max, math.min, math.ceil
+local error, assert, loadstring = error, assert, loadstring
+local setmetatable, rawget, rawset = setmetatable, rawget, rawset
+local math_max = math.max
-- WoW APIs
local UIParent = UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler, LibStub
+
+--local con = LibStub("AceConsole-3.0",true)
+
AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
-AceGUI.tooltip = AceGUI.tooltip or CreateFrame("GameTooltip", "AceGUITooltip", UIParent, "GameTooltipTemplate")
-
+
-- local upvalues
local WidgetRegistry = AceGUI.WidgetRegistry
local LayoutRegistry = AceGUI.LayoutRegistry
@@ -61,10 +66,39 @@ local function errorhandler(err)
return geterrorhandler()(err)
end
+local function CreateDispatcher(argCount)
+ local code = [[
+ local xpcall, eh = ...
+ local method, ARGS
+ local function call() return method(ARGS) end
+
+ local function dispatch(func, ...)
+ method = func
+ if not method then return end
+ ARGS = ...
+ return xpcall(call, eh)
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS = {}
+ for i = 1, argCount do ARGS[i] = "arg"..i end
+ code = code:gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
+end})
+Dispatchers[0] = function(func)
+ return xpcall(func, errorhandler)
+end
+
local function safecall(func, ...)
- if func then
- return xpcall(func, errorhandler, ...)
- end
+ return Dispatchers[select("#", ...)](func, ...)
end
-- Recycling functions
@@ -74,7 +108,7 @@ do
-- Internal Storage of the objects changed, from an array table
-- to a hash table, and additionally we introduced versioning on
-- the widgets which would discard all widgets from a pre-29 version
- -- anyway, so we just clear the storage now, and don't try to
+ -- anyway, so we just clear the storage now, and don't try to
-- convert the storage tables to the new format.
-- This should generally not cause *many* widgets to end up in trash,
-- since once dialogs are opened, all addons should be loaded already
@@ -84,42 +118,42 @@ do
if oldminor and oldminor < 29 and AceGUI.objPools then
AceGUI.objPools = nil
end
-
+
AceGUI.objPools = AceGUI.objPools or {}
local objPools = AceGUI.objPools
--Returns a new instance, if none are available either returns a new table or calls the given contructor
- function newWidget(widgetType)
- if not WidgetRegistry[widgetType] then
+ function newWidget(type)
+ if not WidgetRegistry[type] then
error("Attempt to instantiate unknown widget type", 2)
end
-
- if not objPools[widgetType] then
- objPools[widgetType] = {}
+
+ if not objPools[type] then
+ objPools[type] = {}
end
-
- local newObj = next(objPools[widgetType])
+
+ local newObj = next(objPools[type])
if not newObj then
- newObj = WidgetRegistry[widgetType]()
- newObj.AceGUIWidgetVersion = WidgetVersions[widgetType]
+ newObj = WidgetRegistry[type]()
+ newObj.AceGUIWidgetVersion = WidgetVersions[type]
else
- objPools[widgetType][newObj] = nil
+ objPools[type][newObj] = nil
-- if the widget is older then the latest, don't even try to reuse it
-- just forget about it, and grab a new one.
- if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[widgetType] then
- return newWidget(widgetType)
+ if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[type] then
+ return newWidget(type)
end
end
return newObj
end
-- Releases an instance to the Pool
- function delWidget(obj,widgetType)
- if not objPools[widgetType] then
- objPools[widgetType] = {}
+ function delWidget(obj,type)
+ if not objPools[type] then
+ objPools[type] = {}
end
- if objPools[widgetType][obj] then
+ if objPools[type][obj] then
error("Attempt to Release Widget that is already released", 2)
end
- objPools[widgetType][obj] = true
+ objPools[type][obj] = true
end
end
@@ -135,9 +169,9 @@ end
-- OnAcquire function on it, before returning.
-- @param type The type of the widget.
-- @return The newly created widget.
-function AceGUI:Create(widgetType)
- if WidgetRegistry[widgetType] then
- local widget = newWidget(widgetType)
+function AceGUI:Create(type)
+ if WidgetRegistry[type] then
+ local widget = newWidget(type)
if rawget(widget, "Acquire") then
widget.OnAcquire = widget.Acquire
@@ -146,16 +180,16 @@ function AceGUI:Create(widgetType)
widget.OnAcquire = widget.Aquire
widget.Aquire = nil
end
-
+
if rawget(widget, "Release") then
- widget.OnRelease = rawget(widget, "Release")
+ widget.OnRelease = rawget(widget, "Release")
widget.Release = nil
end
-
+
if widget.OnAcquire then
widget:OnAcquire()
else
- error(("Widget type %s doesn't supply an OnAcquire Function"):format(widgetType))
+ error(("Widget type %s doesn't supply an OnAcquire Function"):format(type))
end
-- Set the default Layout ("List")
safecall(widget.SetLayout, widget, "List")
@@ -170,10 +204,7 @@ end
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
-- @param widget The widget to release
function AceGUI:Release(widget)
- if widget.isQueuedForRelease then return end
- widget.isQueuedForRelease = true
safecall(widget.PauseLayout, widget)
- widget.frame:Hide()
widget:Fire("OnRelease")
safecall(widget.ReleaseChildren, widget)
@@ -202,26 +233,9 @@ function AceGUI:Release(widget)
widget.content.width = nil
widget.content.height = nil
end
- widget.isQueuedForRelease = nil
delWidget(widget, widget.type)
end
---- Check if a widget is currently in the process of being released
--- This function check if this widget, or any of its parents (in which case it'll be released shortly as well)
--- are currently being released. This allows addon to handle any callbacks accordingly.
--- @param widget The widget to check
-function AceGUI:IsReleasing(widget)
- if widget.isQueuedForRelease then
- return true
- end
-
- if widget.parent and widget.parent.AceGUIWidgetVersion then
- return AceGUI:IsReleasing(widget.parent)
- end
-
- return false
-end
-
-----------
-- Focus --
-----------
@@ -253,18 +267,18 @@ end
--[[
Widgets must provide the following functions
OnAcquire() - Called when the object is acquired, should set everything to a default hidden state
-
+
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
-
+
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
-
+
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
-
+
The Widget can supply the following Optional Members
:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data
:OnWidthSet(width) - Called when the width of the widget is changed
@@ -280,21 +294,21 @@ end
-- Widget Base Template --
--------------------------
do
- local WidgetBase = AceGUI.WidgetBase
-
+ local WidgetBase = AceGUI.WidgetBase
+
WidgetBase.SetParent = function(self, parent)
local frame = self.frame
frame:SetParent(nil)
frame:SetParent(parent.content)
self.parent = parent
end
-
+
WidgetBase.SetCallback = function(self, name, func)
if type(func) == "function" then
self.events[name] = func
end
end
-
+
WidgetBase.Fire = function(self, name, ...)
if self.events[name] then
local success, ret = safecall(self.events[name], self, name, ...)
@@ -303,7 +317,7 @@ do
end
end
end
-
+
WidgetBase.SetWidth = function(self, width)
self.frame:SetWidth(width)
self.frame.width = width
@@ -311,7 +325,7 @@ do
self:OnWidthSet(width)
end
end
-
+
WidgetBase.SetRelativeWidth = function(self, width)
if width <= 0 or width > 1 then
error(":SetRelativeWidth(width): Invalid relative width.", 2)
@@ -319,7 +333,7 @@ do
self.relWidth = width
self.width = "relative"
end
-
+
WidgetBase.SetHeight = function(self, height)
self.frame:SetHeight(height)
self.frame.height = height
@@ -327,7 +341,7 @@ do
self:OnHeightSet(height)
end
end
-
+
--[[ WidgetBase.SetRelativeHeight = function(self, height)
if height <= 0 or height > 1 then
error(":SetRelativeHeight(height): Invalid relative height.", 2)
@@ -339,51 +353,47 @@ do
WidgetBase.IsVisible = function(self)
return self.frame:IsVisible()
end
-
+
WidgetBase.IsShown= function(self)
return self.frame:IsShown()
end
-
+
WidgetBase.Release = function(self)
AceGUI:Release(self)
end
-
- WidgetBase.IsReleasing = function(self)
- return AceGUI:IsReleasing(self)
- end
-
+
WidgetBase.SetPoint = function(self, ...)
return self.frame:SetPoint(...)
end
-
+
WidgetBase.ClearAllPoints = function(self)
return self.frame:ClearAllPoints()
end
-
+
WidgetBase.GetNumPoints = function(self)
return self.frame:GetNumPoints()
end
-
+
WidgetBase.GetPoint = function(self, ...)
return self.frame:GetPoint(...)
- end
-
+ end
+
WidgetBase.GetUserDataTable = function(self)
return self.userdata
end
-
+
WidgetBase.SetUserData = function(self, key, value)
self.userdata[key] = value
end
-
+
WidgetBase.GetUserData = function(self, key)
return self.userdata[key]
end
-
+
WidgetBase.IsFullHeight = function(self)
return self.height == "fill"
end
-
+
WidgetBase.SetFullHeight = function(self, isFull)
if isFull then
self.height = "fill"
@@ -391,11 +401,11 @@ do
self.height = nil
end
end
-
+
WidgetBase.IsFullWidth = function(self)
return self.width == "fill"
end
-
+
WidgetBase.SetFullWidth = function(self, isFull)
if isFull then
self.width = "fill"
@@ -403,29 +413,29 @@ do
self.width = nil
end
end
-
+
-- local function LayoutOnUpdate(this)
-- this:SetScript("OnUpdate",nil)
-- this.obj:PerformLayout()
-- end
-
+
local WidgetContainerBase = AceGUI.WidgetContainerBase
-
+
WidgetContainerBase.PauseLayout = function(self)
self.LayoutPaused = true
end
-
+
WidgetContainerBase.ResumeLayout = function(self)
self.LayoutPaused = nil
end
-
+
WidgetContainerBase.PerformLayout = function(self)
if self.LayoutPaused then
return
end
safecall(self.LayoutFunc, self.content, self.children)
end
-
+
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
WidgetContainerBase.DoLayout = function(self)
self:PerformLayout()
@@ -433,7 +443,7 @@ do
-- self.frame:SetScript("OnUpdate", LayoutOnUpdate)
-- end
end
-
+
WidgetContainerBase.AddChild = function(self, child, beforeWidget)
if beforeWidget then
local siblingIndex = 1
@@ -441,7 +451,7 @@ do
if widget == beforeWidget then
break
end
- siblingIndex = siblingIndex + 1
+ siblingIndex = siblingIndex + 1
end
tinsert(self.children, siblingIndex, child)
else
@@ -451,7 +461,7 @@ do
child.frame:Show()
self:DoLayout()
end
-
+
WidgetContainerBase.AddChildren = function(self, ...)
for i = 1, select("#", ...) do
local child = select(i, ...)
@@ -461,7 +471,7 @@ do
end
self:DoLayout()
end
-
+
WidgetContainerBase.ReleaseChildren = function(self)
local children = self.children
for i = 1,#children do
@@ -469,7 +479,7 @@ do
children[i] = nil
end
end
-
+
WidgetContainerBase.SetLayout = function(self, Layout)
self.LayoutFunc = AceGUI:GetLayout(Layout)
end
@@ -493,7 +503,7 @@ do
end
end
end
-
+
local function ContentResize(this)
if this:GetWidth() and this:GetHeight() then
this.width = this:GetWidth()
@@ -505,7 +515,7 @@ do
setmetatable(WidgetContainerBase, {__index=WidgetBase})
--One of these function should be called on each Widget Instance as part of its creation process
-
+
--- Register a widget-class as a container for newly created widgets.
-- @param widget The widget class
function AceGUI:RegisterAsContainer(widget)
@@ -521,7 +531,7 @@ do
widget:SetLayout("List")
return widget
end
-
+
--- Register a widget-class as a widget.
-- @param widget The widget class
function AceGUI:RegisterAsWidget(widget)
@@ -548,11 +558,11 @@ end
-- @param Version The version of the widget
function AceGUI:RegisterWidgetType(Name, Constructor, Version)
assert(type(Constructor) == "function")
- assert(type(Version) == "number")
-
+ assert(type(Version) == "number")
+
local oldVersion = WidgetVersions[Name]
if oldVersion and oldVersion >= Version then return end
-
+
WidgetVersions[Name] = Version
WidgetRegistry[Name] = Constructor
end
@@ -583,25 +593,25 @@ AceGUI.counts = AceGUI.counts or {}
-- This is used by widgets that require a named frame, e.g. when a Blizzard
-- Template requires it.
-- @param type The widget type
-function AceGUI:GetNextWidgetNum(widgetType)
- if not self.counts[widgetType] then
- self.counts[widgetType] = 0
+function AceGUI:GetNextWidgetNum(type)
+ if not self.counts[type] then
+ self.counts[type] = 0
end
- self.counts[widgetType] = self.counts[widgetType] + 1
- return self.counts[widgetType]
+ self.counts[type] = self.counts[type] + 1
+ return self.counts[type]
end
--- Return the number of created widgets for this type.
-- In contrast to GetNextWidgetNum, the number is not incremented.
--- @param widgetType The widget type
-function AceGUI:GetWidgetCount(widgetType)
- return self.counts[widgetType] or 0
+-- @param type The widget type
+function AceGUI:GetWidgetCount(type)
+ return self.counts[type] or 0
end
--- Return the version of the currently registered widget type.
--- @param widgetType The widget type
-function AceGUI:GetWidgetVersion(widgetType)
- return WidgetVersions[widgetType]
+-- @param type The widget type
+function AceGUI:GetWidgetVersion(type)
+ return WidgetVersions[type]
end
-------------
@@ -621,7 +631,7 @@ AceGUI:RegisterLayout("List",
local width = content.width or content:GetWidth() or 0
for i = 1, #children do
local child = children[i]
-
+
local frame = child.frame
frame:ClearAllPoints()
frame:Show()
@@ -630,22 +640,22 @@ AceGUI:RegisterLayout("List",
else
frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT")
end
-
+
if child.width == "fill" then
child:SetWidth(width)
frame:SetPoint("RIGHT", content)
-
+
if child.DoLayout then
child:DoLayout()
end
elseif child.width == "relative" then
child:SetWidth(width * child.relWidth)
-
+
if child.DoLayout then
child:DoLayout()
end
end
-
+
height = height + (frame.height or frame:GetHeight() or 0)
end
safecall(content.obj.LayoutFinished, content.obj, nil, height)
@@ -657,23 +667,14 @@ AceGUI:RegisterLayout("Fill",
if children[1] then
children[1]:SetWidth(content:GetWidth() or 0)
children[1]:SetHeight(content:GetHeight() or 0)
- children[1].frame:ClearAllPoints()
children[1].frame:SetAllPoints(content)
children[1].frame:Show()
safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight())
end
end)
-local layoutrecursionblock = nil
-local function safelayoutcall(object, func, ...)
- layoutrecursionblock = true
- object[func](object, ...)
- layoutrecursionblock = nil
-end
-
AceGUI:RegisterLayout("Flow",
function(content, children)
- if layoutrecursionblock then return end
--used height so far
local height = 0
--width used in the current row
@@ -681,17 +682,19 @@ AceGUI:RegisterLayout("Flow",
--height of the current row
local rowheight = 0
local rowoffset = 0
-
+ local lastrowoffset
+
local width = content.width or content:GetWidth() or 0
-
+
--control at the start of the row
local rowstart
local rowstartoffset
+ local lastrowstart
local isfullheight
-
+
local frameoffset
local lastframeoffset
- local oversize
+ local oversize
for i = 1, #children do
local child = children[i]
oversize = nil
@@ -699,17 +702,17 @@ AceGUI:RegisterLayout("Flow",
local frameheight = frame.height or frame:GetHeight() or 0
local framewidth = frame.width or frame:GetWidth() or 0
lastframeoffset = frameoffset
- -- HACK: Why did we set a frameoffset of (frameheight / 2) ?
+ -- HACK: Why did we set a frameoffset of (frameheight / 2) ?
-- That was moving all widgets half the widgets size down, is that intended?
-- Actually, it seems to be neccessary for many cases, we'll leave it in for now.
-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them.
-- TODO: Investigate moar!
frameoffset = child.alignoffset or (frameheight / 2)
-
+
if child.width == "relative" then
framewidth = width * child.relWidth
end
-
+
frame:Show()
frame:ClearAllPoints()
if i == 1 then
@@ -748,23 +751,24 @@ AceGUI:RegisterLayout("Flow",
else
--handles cases where the new height is higher than either control because of the offsets
--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset)
-
+
--offset is always the larger of the two offsets
rowoffset = math_max(rowoffset, frameoffset)
rowheight = math_max(rowheight, rowoffset + (frameheight / 2))
-
+
frame:SetPoint("TOPLEFT", children[i-1].frame, "TOPRIGHT", 0, frameoffset - lastframeoffset)
usedwidth = framewidth + usedwidth
end
end
if child.width == "fill" then
- safelayoutcall(child, "SetWidth", width)
+ child:SetWidth(width)
frame:SetPoint("RIGHT", content)
-
+
usedwidth = 0
rowstart = frame
-
+ rowstartoffset = frameoffset
+
if child.DoLayout then
child:DoLayout()
end
@@ -772,8 +776,8 @@ AceGUI:RegisterLayout("Flow",
rowoffset = child.alignoffset or (rowheight / 2)
rowstartoffset = rowoffset
elseif child.width == "relative" then
- safelayoutcall(child, "SetWidth", width * child.relWidth)
-
+ child:SetWidth(width * child.relWidth)
+
if child.DoLayout then
child:DoLayout()
end
@@ -782,239 +786,20 @@ AceGUI:RegisterLayout("Flow",
frame:SetPoint("RIGHT", content)
end
end
-
+
if child.height == "fill" then
frame:SetPoint("BOTTOM", content)
isfullheight = true
end
end
-
+
--anchor the last row, if its full height needs a special case since its height has just been changed by the anchor
if isfullheight then
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -height)
elseif rowstart then
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
end
-
+
height = height + rowheight + 3
safecall(content.obj.LayoutFinished, content.obj, nil, height)
end)
-
--- Get alignment method and value. Possible alignment methods are a callback, a number, "start", "middle", "end", "fill" or "TOPLEFT", "BOTTOMRIGHT" etc.
-local GetCellAlign = function (dir, tableObj, colObj, cellObj, cell, child)
- local fn = cellObj and (cellObj["align" .. dir] or cellObj.align)
- or colObj and (colObj["align" .. dir] or colObj.align)
- or tableObj["align" .. dir] or tableObj.align
- or "CENTERLEFT"
- local val
- child, cell = child or 0, cell or 0
-
- if type(fn) == "string" then
- fn = fn:lower()
- fn = dir == "V" and (fn:sub(1, 3) == "top" and "start" or fn:sub(1, 6) == "bottom" and "end" or fn:sub(1, 6) == "center" and "middle")
- or dir == "H" and (fn:sub(-4) == "left" and "start" or fn:sub(-5) == "right" and "end" or fn:sub(-6) == "center" and "middle")
- or fn
- val = (fn == "start" or fn == "fill") and 0 or fn == "end" and cell - child or (cell - child) / 2
- elseif type(fn) == "function" then
- val = fn(child or 0, cell, dir)
- else
- val = fn
- end
-
- return fn, math_max(0, math_min(val, cell))
-end
-
--- Get width or height for multiple cells combined
-local GetCellDimension = function (dir, laneDim, from, to, space)
- local dim = 0
- for cell=from,to do
- dim = dim + (laneDim[cell] or 0)
- end
- return dim + math_max(0, to - from) * (space or 0)
-end
-
---[[ Options
-============
-Container:
- - columns ({col, col, ...}): Column settings. "col" can be a number (<= 0: content width, <1: rel. width, <10: weight, >=10: abs. width) or a table with column setting.
- - space, spaceH, spaceV: Overall, horizontal and vertical spacing between cells.
- - align, alignH, alignV: Overall, horizontal and vertical cell alignment. See GetCellAlign() for possible values.
-Columns:
- - width: Fixed column width (nil or <=0: content width, <1: rel. width, >=1: abs. width).
- - min or 1: Min width for content based width
- - max or 2: Max width for content based width
- - weight: Flexible column width. The leftover width after accounting for fixed-width columns is distributed to weighted columns according to their weights.
- - align, alignH, alignV: Overwrites the container setting for alignment.
-Cell:
- - colspan: Makes a cell span multiple columns.
- - rowspan: Makes a cell span multiple rows.
- - align, alignH, alignV: Overwrites the container and column setting for alignment.
-]]
-AceGUI:RegisterLayout("Table",
- function (content, children)
- local obj = content.obj
- obj:PauseLayout()
-
- local tableObj = obj:GetUserData("table")
- local cols = tableObj.columns
- local spaceH = tableObj.spaceH or tableObj.space or 0
- local spaceV = tableObj.spaceV or tableObj.space or 0
- local totalH = (content:GetWidth() or content.width or 0) - spaceH * (#cols - 1)
-
- -- We need to reuse these because layout events can come in very frequently
- local layoutCache = obj:GetUserData("layoutCache")
- if not layoutCache then
- layoutCache = {{}, {}, {}, {}, {}, {}}
- obj:SetUserData("layoutCache", layoutCache)
- end
- local t, laneH, laneV, rowspans, rowStart, colStart = unpack(layoutCache)
-
- -- Create the grid
- local n, slotFound = 0
- for i,child in ipairs(children) do
- if child:IsShown() then
- repeat
- n = n + 1
- local col = (n - 1) % #cols + 1
- local row = math_ceil(n / #cols)
- local rowspan = rowspans[col]
- local cell = rowspan and rowspan.child or child
- local cellObj = cell:GetUserData("cell")
- slotFound = not rowspan
-
- -- Rowspan
- if not rowspan and cellObj and cellObj.rowspan then
- rowspan = {child = child, from = row, to = row + cellObj.rowspan - 1}
- rowspans[col] = rowspan
- end
- if rowspan and i == #children then
- rowspan.to = row
- end
-
- -- Colspan
- local colspan = math_max(0, math_min((cellObj and cellObj.colspan or 1) - 1, #cols - col))
- n = n + colspan
-
- -- Place the cell
- if not rowspan or rowspan.to == row then
- t[n] = cell
- rowStart[cell] = rowspan and rowspan.from or row
- colStart[cell] = col
-
- if rowspan then
- rowspans[col] = nil
- end
- end
- until slotFound
- end
- end
-
- local rows = math_ceil(n / #cols)
-
- -- Determine fixed size cols and collect weights
- local extantH, totalWeight = totalH, 0
- for col,colObj in ipairs(cols) do
- laneH[col] = 0
-
- if type(colObj) == "number" then
- colObj = {[colObj >= 1 and colObj < 10 and "weight" or "width"] = colObj}
- cols[col] = colObj
- end
-
- if colObj.weight then
- -- Weight
- totalWeight = totalWeight + (colObj.weight or 1)
- else
- if not colObj.width or colObj.width <= 0 then
- -- Content width
- for row=1,rows do
- local child = t[(row - 1) * #cols + col]
- if child then
- local f = child.frame
- f:ClearAllPoints()
- local childH = f:GetWidth() or 0
-
- laneH[col] = math_max(laneH[col], childH - GetCellDimension("H", laneH, colStart[child], col - 1, spaceH))
- end
- end
-
- laneH[col] = math_max(colObj.min or colObj[1] or 0, math_min(laneH[col], colObj.max or colObj[2] or laneH[col]))
- else
- -- Rel./Abs. width
- laneH[col] = colObj.width < 1 and colObj.width * totalH or colObj.width
- end
- extantH = math_max(0, extantH - laneH[col])
- end
- end
-
- -- Determine sizes based on weight
- local scale = totalWeight > 0 and extantH / totalWeight or 0
- for col,colObj in pairs(cols) do
- if colObj.weight then
- laneH[col] = scale * colObj.weight
- end
- end
-
- -- Arrange children
- for row=1,rows do
- local rowV = 0
-
- -- Horizontal placement and sizing
- for col=1,#cols do
- local child = t[(row - 1) * #cols + col]
- if child then
- local colObj = cols[colStart[child]]
- local cellObj = child:GetUserData("cell")
- local offsetH = GetCellDimension("H", laneH, 1, colStart[child] - 1, spaceH) + (colStart[child] == 1 and 0 or spaceH)
- local cellH = GetCellDimension("H", laneH, colStart[child], col, spaceH)
-
- local f = child.frame
- f:ClearAllPoints()
- local childH = f:GetWidth() or 0
-
- local alignFn, align = GetCellAlign("H", tableObj, colObj, cellObj, cellH, childH)
- f:SetPoint("LEFT", content, offsetH + align, 0)
- if child:IsFullWidth() or alignFn == "fill" or childH > cellH then
- f:SetPoint("RIGHT", content, "LEFT", offsetH + align + cellH, 0)
- end
-
- if child.DoLayout then
- child:DoLayout()
- end
-
- rowV = math_max(rowV, (f:GetHeight() or 0) - GetCellDimension("V", laneV, rowStart[child], row - 1, spaceV))
- end
- end
-
- laneV[row] = rowV
-
- -- Vertical placement and sizing
- for col=1,#cols do
- local child = t[(row - 1) * #cols + col]
- if child then
- local colObj = cols[colStart[child]]
- local cellObj = child:GetUserData("cell")
- local offsetV = GetCellDimension("V", laneV, 1, rowStart[child] - 1, spaceV) + (rowStart[child] == 1 and 0 or spaceV)
- local cellV = GetCellDimension("V", laneV, rowStart[child], row, spaceV)
-
- local f = child.frame
- local childV = f:GetHeight() or 0
-
- local alignFn, align = GetCellAlign("V", tableObj, colObj, cellObj, cellV, childV)
- if child:IsFullHeight() or alignFn == "fill" then
- f:SetHeight(cellV)
- end
- f:SetPoint("TOP", content, 0, -(offsetV + align))
- end
- end
- end
-
- -- Calculate total height
- local totalV = GetCellDimension("V", laneV, 1, #laneV, spaceV)
-
- -- Cleanup
- for _,v in pairs(layoutCache) do wipe(v) end
-
- safecall(obj.LayoutFinished, obj, nil, totalV)
- obj:ResumeLayout()
- end)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
index 4f635d8..7f92d82 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
@@ -2,7 +2,7 @@
BlizOptionsGroup Container
Simple container widget for the integration of AceGUI into the Blizzard Interface Options
-------------------------------------------------------------------------------]]
-local Type, Version = "BlizOptionsGroup", 26
+local Type, Version = "BlizOptionsGroup", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -36,12 +36,8 @@ local function cancel(frame)
frame.obj:Fire("cancel")
end
-local function default(frame)
- frame.obj:Fire("default")
-end
-
-local function refresh(frame)
- frame.obj:Fire("refresh")
+local function defaults(frame)
+ frame.obj:Fire("defaults")
end
--[[-----------------------------------------------------------------------------
@@ -99,23 +95,13 @@ local methods = {
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
- -- CoA-compat: InterfaceOptionsFramePanelContainer is a global from the stock 3.3.5
- -- Interface Options frame; on the CoA reworked FrameXML it can be nil at the time
- -- AceGUI widgets are constructed. Fall back to UIParent so CreateFrame doesn't blow up.
- local _parent = InterfaceOptionsFramePanelContainer or UIParent
- local frame = CreateFrame("Frame", nil, _parent)
+ local frame = CreateFrame("Frame")
frame:Hide()
-- support functions for the Blizzard Interface Options
frame.okay = okay
frame.cancel = cancel
- frame.default = default
- frame.refresh = refresh
-
- -- 10.0 support function aliases (cancel has been removed)
- frame.OnCommit = okay
- frame.OnDefault = default
- frame.OnRefresh = refresh
+ frame.defaults = defaults
frame:SetScript("OnHide", OnHide)
frame:SetScript("OnShow", OnShow)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
index cd83755..083a9f7 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
@@ -2,7 +2,7 @@
DropdownGroup Container
Container controlled by a dropdown on the top.
-------------------------------------------------------------------------------]]
-local Type, Version = "DropdownGroup", 22
+local Type, Version = "DropdownGroup", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -50,8 +50,8 @@ local methods = {
end
end,
- ["SetGroupList"] = function(self,list,order)
- self.dropdown:SetList(list,order)
+ ["SetGroupList"] = function(self,list)
+ self.dropdown:SetList(list)
end,
["SetStatusTable"] = function(self, status)
@@ -125,7 +125,7 @@ local function Constructor()
dropdown.frame:Show()
dropdown:SetLabel("")
- local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local border = CreateFrame("Frame", nil, frame)
border:SetPoint("TOPLEFT", 0, -26)
border:SetPoint("BOTTOMRIGHT", 0, 3)
border:SetBackdrop(PaneBackdrop)
@@ -150,7 +150,7 @@ local function Constructor()
widget[method] = func
end
dropdown.parentgroup = widget
-
+
return AceGUI:RegisterAsContainer(widget)
end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
index 0065c70..b35797b 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
@@ -1,7 +1,7 @@
--[[-----------------------------------------------------------------------------
Frame Container
-------------------------------------------------------------------------------]]
-local Type, Version = "Frame", 30
+local Type, Version = "Frame", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -13,18 +13,18 @@ local wipe = table.wipe
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Button_OnClick(frame)
- PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+ PlaySound("gsTitleOptionExit")
frame.obj:Hide()
end
-local function Frame_OnShow(frame)
- frame.obj:Fire("OnShow")
-end
-
local function Frame_OnClose(frame)
frame.obj:Fire("OnClose")
end
@@ -79,12 +79,10 @@ local methods = {
["OnAcquire"] = function(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
- self.frame:SetFrameLevel(100) -- Lots of room to draw under it
self:SetTitle()
self:SetStatusText()
self:ApplyStatus()
self:Show()
- self:EnableResize(true)
end,
["OnRelease"] = function(self)
@@ -114,7 +112,6 @@ local methods = {
["SetTitle"] = function(self, title)
self.titletext:SetText(title)
- self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
end,
["SetStatusText"] = function(self, text)
@@ -129,13 +126,6 @@ local methods = {
self.frame:Show()
end,
- ["EnableResize"] = function(self, state)
- local func = state and "Show" or "Hide"
- self.sizer_se[func](self.sizer_se)
- self.sizer_s[func](self.sizer_s)
- self.sizer_e[func](self.sizer_e)
- end,
-
-- called to set an external table to store status in
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
@@ -176,23 +166,17 @@ local PaneBackdrop = {
}
local function Constructor()
- local frame = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
+ local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
frame:EnableMouse(true)
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
- frame:SetFrameLevel(100) -- Lots of room to draw under it
frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0, 0, 0, 1)
- if frame.SetResizeBounds then -- WoW 10.0
- frame:SetResizeBounds(400, 200)
- else
- frame:SetMinResize(400, 200)
- end
+ frame:SetMinResize(400, 200)
frame:SetToplevel(true)
- frame:SetScript("OnShow", Frame_OnShow)
frame:SetScript("OnHide", Frame_OnClose)
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
@@ -203,7 +187,7 @@ local function Constructor()
closebutton:SetWidth(100)
closebutton:SetText(CLOSE)
- local statusbg = CreateFrame("Button", nil, frame, "BackdropTemplate")
+ local statusbg = CreateFrame("Button", nil, frame)
statusbg:SetPoint("BOTTOMLEFT", 15, 15)
statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
statusbg:SetHeight(24)
@@ -271,7 +255,7 @@ local function Constructor()
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
- x = 0.1 * 8/17
+ local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame", nil, frame)
@@ -299,10 +283,6 @@ local function Constructor()
localstatus = {},
titletext = titletext,
statustext = statustext,
- titlebg = titlebg,
- sizer_se = sizer_se,
- sizer_s = sizer_s,
- sizer_e = sizer_e,
content = content,
frame = frame,
type = Type
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
index 1676ae4..9413611 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
@@ -2,7 +2,7 @@
InlineGroup Container
Simple container widget that creates a visible "box" with an optional title.
-------------------------------------------------------------------------------]]
-local Type, Version = "InlineGroup", 22
+local Type, Version = "InlineGroup", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -19,7 +19,6 @@ local methods = {
["OnAcquire"] = function(self)
self:SetWidth(300)
self:SetHeight(100)
- self:SetTitle("")
end,
-- ["OnRelease"] = nil,
@@ -75,7 +74,7 @@ local function Constructor()
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
- local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local border = CreateFrame("Frame", nil, frame)
border:SetPoint("TOPLEFT", 0, -17)
border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
index d110d03..97e3b5f 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
@@ -2,7 +2,7 @@
ScrollFrame Container
Plain container that scrolls its content and doesn't grow in height.
-------------------------------------------------------------------------------]]
-local Type, Version = "ScrollFrame", 26
+local Type, Version = "ScrollFrame", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -40,9 +40,8 @@ end
Methods
-------------------------------------------------------------------------------]]
local methods = {
- ["OnAcquire"] = function(self)
+ ["OnAcquire"] = function(self)
self:SetScroll(0)
- self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end,
["OnRelease"] = function(self)
@@ -53,7 +52,7 @@ local methods = {
self.scrollframe:SetPoint("BOTTOMRIGHT")
self.scrollbar:Hide()
self.scrollBarShown = nil
- self.content.height, self.content.width, self.content.original_width = nil, nil, nil
+ self.content.height, self.content.width = nil, nil
end,
["SetScroll"] = function(self, value)
@@ -77,8 +76,11 @@ local methods = {
["MoveScroll"] = function(self, value)
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
-
- if self.scrollBarShown then
+
+ if height > viewheight then
+ self.scrollbar:Hide()
+ else
+ self.scrollbar:Show()
local diff = height - viewheight
local delta = 1
if value < 0 then
@@ -94,17 +96,13 @@ local methods = {
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
local offset = status.offset or 0
- -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
- -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
- if viewheight < height + 2 then
+ local curvalue = self.scrollbar:GetValue()
+ if viewheight < height then
if self.scrollBarShown then
self.scrollBarShown = nil
self.scrollbar:Hide()
self.scrollbar:SetValue(0)
self.scrollframe:SetPoint("BOTTOMRIGHT")
- if self.content.original_width then
- self.content.width = self.content.original_width
- end
self:DoLayout()
end
else
@@ -112,9 +110,6 @@ local methods = {
self.scrollBarShown = true
self.scrollbar:Show()
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
- if self.content.original_width then
- self.content.width = self.content.original_width - 20
- end
self:DoLayout()
end
local value = (offset / (viewheight - height) * 1000)
@@ -133,11 +128,6 @@ local methods = {
["LayoutFinished"] = function(self, width, height)
self.content:SetHeight(height or 0 + 20)
-
- -- update the scrollframe
- self:FixScroll()
-
- -- schedule another update when everything has "settled"
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end,
@@ -151,8 +141,7 @@ local methods = {
["OnWidthSet"] = function(self, width)
local content = self.content
- content.width = width - (self.scrollBarShown and 20 or 0)
- content.original_width = width
+ content.width = width
end,
["OnHeightSet"] = function(self, height)
@@ -187,7 +176,7 @@ local function Constructor()
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
- scrollbg:SetColorTexture(0, 0, 0, 0.4)
+ scrollbg:SetTexture(0, 0, 0, 0.4)
--Container Support
local content = CreateFrame("Frame", nil, scrollframe)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
index 8e46876..8287696 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
@@ -2,18 +2,22 @@
TabGroup Container
Container that uses tabs on top to switch between groups.
-------------------------------------------------------------------------------]]
-local Type, Version = "TabGroup", 38
+local Type, Version = "TabGroup", 30
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
-local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, table.wipe
+local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
-- WoW APIs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
+
-- local upvalue storage used by BuildTabs
local widths = {}
local rowwidths = {}
@@ -22,143 +26,6 @@ local rowends = {}
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
-
-local function PanelTemplates_TabResize(tab, padding, absoluteSize, minWidth, maxWidth, absoluteTextSize)
- local tabName = tab:GetName();
-
- local buttonMiddle = tab.Middle or tab.middleTexture or _G[tabName.."Middle"];
- local buttonMiddleDisabled = tab.MiddleDisabled or (tabName and _G[tabName.."MiddleDisabled"]);
- local left = tab.Left or tab.leftTexture or _G[tabName.."Left"];
- local sideWidths = 2 * left:GetWidth();
- local tabText = tab.Text or _G[tab:GetName().."Text"];
- local highlightTexture = tab.HighlightTexture or (tabName and _G[tabName.."HighlightTexture"]);
-
- local width, tabWidth;
- local textWidth;
- if ( absoluteTextSize ) then
- textWidth = absoluteTextSize;
- else
- tabText:SetWidth(0);
- textWidth = tabText:GetWidth();
- end
- -- If there's an absolute size specified then use it
- if ( absoluteSize ) then
- if ( absoluteSize < sideWidths) then
- width = 1;
- tabWidth = sideWidths
- else
- width = absoluteSize - sideWidths;
- tabWidth = absoluteSize
- end
- tabText:SetWidth(width);
- else
- -- Otherwise try to use padding
- if ( padding ) then
- width = textWidth + padding;
- else
- width = textWidth + 24;
- end
- -- If greater than the maxWidth then cap it
- if ( maxWidth and width > maxWidth ) then
- if ( padding ) then
- width = maxWidth + padding;
- else
- width = maxWidth + 24;
- end
- tabText:SetWidth(width);
- else
- tabText:SetWidth(0);
- end
- if (minWidth and width < minWidth) then
- width = minWidth;
- end
- tabWidth = width + sideWidths;
- end
-
- if ( buttonMiddle ) then
- buttonMiddle:SetWidth(width);
- end
- if ( buttonMiddleDisabled ) then
- buttonMiddleDisabled:SetWidth(width);
- end
-
- tab:SetWidth(tabWidth);
-
- if ( highlightTexture ) then
- highlightTexture:SetWidth(tabWidth);
- end
-end
-
-local function PanelTemplates_DeselectTab(tab)
- local name = tab:GetName();
-
- local left = tab.Left or _G[name.."Left"];
- local middle = tab.Middle or _G[name.."Middle"];
- local right = tab.Right or _G[name.."Right"];
- left:Show();
- middle:Show();
- right:Show();
- --tab:UnlockHighlight();
- tab:Enable();
- local text = tab.Text or _G[name.."Text"];
- text:SetPoint("CENTER", tab, "CENTER", (tab.deselectedTextX or 0), (tab.deselectedTextY or 2));
-
- local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
- local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
- local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
- leftDisabled:Hide();
- middleDisabled:Hide();
- rightDisabled:Hide();
-end
-
-local function PanelTemplates_SelectTab(tab)
- local name = tab:GetName();
-
- local left = tab.Left or _G[name.."Left"];
- local middle = tab.Middle or _G[name.."Middle"];
- local right = tab.Right or _G[name.."Right"];
- left:Hide();
- middle:Hide();
- right:Hide();
- --tab:LockHighlight();
- tab:Disable();
- tab:SetDisabledFontObject(GameFontHighlightSmall);
- local text = tab.Text or _G[name.."Text"];
- text:SetPoint("CENTER", tab, "CENTER", (tab.selectedTextX or 0), (tab.selectedTextY or -3));
-
- local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
- local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
- local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
- leftDisabled:Show();
- middleDisabled:Show();
- rightDisabled:Show();
-
- if GameTooltip:IsOwned(tab) then
- GameTooltip:Hide();
- end
-end
-
-local function PanelTemplates_SetDisabledTabState(tab)
- local name = tab:GetName();
- local left = tab.Left or _G[name.."Left"];
- local middle = tab.Middle or _G[name.."Middle"];
- local right = tab.Right or _G[name.."Right"];
- left:Show();
- middle:Show();
- right:Show();
- --tab:UnlockHighlight();
- tab:Disable();
- tab.text = tab:GetText();
- -- Gray out text
- tab:SetDisabledFontObject(GameFontDisableSmall);
- local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
- local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
- local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
- leftDisabled:Hide();
- middleDisabled:Hide();
- rightDisabled:Hide();
-end
-
local function UpdateTabLook(frame)
if frame.disabled then
PanelTemplates_SetDisabledTabState(frame)
@@ -172,7 +39,7 @@ end
local function Tab_SetText(frame, text)
frame:_SetText(text)
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
- PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
+ PanelTemplates_TabResize(frame, 0, nil, width)
end
local function Tab_SetSelected(frame, selected)
@@ -196,7 +63,7 @@ Scripts
-------------------------------------------------------------------------------]]
local function Tab_OnClick(frame)
if not (frame.selected or frame.disabled) then
- PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
+ PlaySound("igCharacterInfoTab")
frame.obj:SelectTab(frame.value)
end
end
@@ -236,64 +103,11 @@ local methods = {
["CreateTab"] = function(self, id)
local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
- local tab = CreateFrame("Button", tabname, self.border)
- tab:SetSize(115, 24)
- tab.deselectedTextY = -3
- tab.selectedTextY = -2
-
- tab.LeftDisabled = tab:CreateTexture(tabname .. "LeftDisabled", "BORDER")
- tab.LeftDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
- tab.LeftDisabled:SetSize(20, 24)
- tab.LeftDisabled:SetPoint("BOTTOMLEFT", 0, -3)
- tab.LeftDisabled:SetTexCoord(0, 0.15625, 0, 1.0)
-
- tab.MiddleDisabled = tab:CreateTexture(tabname .. "MiddleDisabled", "BORDER")
- tab.MiddleDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
- tab.MiddleDisabled:SetSize(88, 24)
- tab.MiddleDisabled:SetPoint("LEFT", tab.LeftDisabled, "RIGHT")
- tab.MiddleDisabled:SetTexCoord(0.15625, 0.84375, 0, 1.0)
-
- tab.RightDisabled = tab:CreateTexture(tabname .. "RightDisabled", "BORDER")
- tab.RightDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
- tab.RightDisabled:SetSize(20, 24)
- tab.RightDisabled:SetPoint("LEFT", tab.MiddleDisabled, "RIGHT")
- tab.RightDisabled:SetTexCoord(0.84375, 1.0, 0, 1.0)
-
- tab.Left = tab:CreateTexture(tabname .. "Left", "BORDER")
- tab.Left:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
- tab.Left:SetSize(20, 24)
- tab.Left:SetPoint("TOPLEFT")
- tab.Left:SetTexCoord(0, 0.15625, 0, 1.0)
-
- tab.Middle = tab:CreateTexture(tabname .. "Middle", "BORDER")
- tab.Middle:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
- tab.Middle:SetSize(88, 24)
- tab.Middle:SetPoint("LEFT", tab.Left, "RIGHT")
- tab.Middle:SetTexCoord(0.15625, 0.84375, 0, 1.0)
-
- tab.Right = tab:CreateTexture(tabname .. "Right", "BORDER")
- tab.Right:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
- tab.Right:SetSize(20, 24)
- tab.Right:SetPoint("LEFT", tab.Middle, "RIGHT")
- tab.Right:SetTexCoord(0.84375, 1.0, 0, 1.0)
-
- tab.Text = tab:CreateFontString(tabname .. "Text")
- tab:SetFontString(tab.Text)
-
- tab:SetNormalFontObject(GameFontNormalSmall)
- tab:SetHighlightFontObject(GameFontHighlightSmall)
- tab:SetDisabledFontObject(GameFontHighlightSmall)
- tab:SetHighlightTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight", "ADD")
- tab.HighlightTexture = tab:GetHighlightTexture()
- tab.HighlightTexture:ClearAllPoints()
- tab.HighlightTexture:SetPoint("LEFT", tab, "LEFT", 10, -4)
- tab.HighlightTexture:SetPoint("RIGHT", tab, "RIGHT", -10, -4)
- _G[tabname .. "HighlightTexture"] = tab.HighlightTexture
-
+ local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
tab.obj = self
tab.id = id
- tab.text = tab.Text -- compat
+ tab.text = _G[tabname .. "Text"]
tab.text:ClearAllPoints()
tab.text:SetPoint("LEFT", 14, -3)
tab.text:SetPoint("RIGHT", -12, -3)
@@ -347,21 +161,22 @@ local methods = {
self.tablist = tabs
self:BuildTabs()
end,
-
+
["BuildTabs"] = function(self)
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
+ local status = self.status or self.localstatus
local tablist = self.tablist
local tabs = self.tabs
-
+
if not tablist then return end
-
+
local width = self.frame.width or self.frame:GetWidth() or 0
-
+
wipe(widths)
wipe(rowwidths)
wipe(rowends)
-
+
--Place Text into tabs and get thier initial width
for i, v in ipairs(tablist) do
local tab = tabs[i]
@@ -369,19 +184,19 @@ local methods = {
tab = self:CreateTab(i)
tabs[i] = tab
end
-
+
tab:Show()
tab:SetText(v.text)
tab:SetDisabled(v.disabled)
tab.value = v.value
-
+
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
end
-
+
for i = (#tablist)+1, #tabs, 1 do
tabs[i]:Hide()
end
-
+
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
local numtabs = #tablist
local numrows = 1
@@ -399,7 +214,7 @@ local methods = {
end
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = #tablist
-
+
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
if numrows > 1 then
--if the last row has only one tab
@@ -430,22 +245,20 @@ local methods = {
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
end
end
-
+
-- equal padding for each tab to fill the available width,
-- if the used space is above 75% already
- -- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
- -- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
local padding = 0
- if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
+ if not (numrows == 1 and rowwidths[1] < width*0.75) then
padding = (width - rowwidths[row]) / (endtab - starttab+1)
end
-
+
for i = starttab, endtab do
- PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
+ PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
end
starttab = endtab + 1
end
-
+
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
end,
@@ -471,7 +284,7 @@ local methods = {
content:SetHeight(contentheight)
content.height = contentheight
end,
-
+
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + (self.borderoffset + 23))
@@ -502,7 +315,7 @@ local function Constructor()
titletext:SetHeight(18)
titletext:SetText("")
- local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local border = CreateFrame("Frame", nil, frame)
border:SetPoint("TOPLEFT", 1, -27)
border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop)
@@ -528,7 +341,7 @@ local function Constructor()
for method, func in pairs(methods) do
widget[method] = func
end
-
+
return AceGUI:RegisterAsContainer(widget)
end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
index b282e19..a5b7916 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
@@ -2,18 +2,22 @@
TreeGroup Container
Container that uses a tree control to switch between groups.
-------------------------------------------------------------------------------]]
-local Type, Version = "TreeGroup", 49
+local Type, Version = "TreeGroup", 30
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
-local math_min, math_max, floor = math.min, math.max, math.floor
-local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
+local math_min, math_max, floor = math.min, math.max, floor
+local select, tremove, unpack = select, table.remove, unpack
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
+
-- Recycling functions
local new, del
do
@@ -30,7 +34,7 @@ do
function del(t)
for k in pairs(t) do
t[k] = nil
- end
+ end
pool[t] = true
end
end
@@ -53,6 +57,7 @@ end
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
local self = button.obj
local toggle = button.toggle
+ local frame = self.frame
local text = treeline.text or ""
local icon = treeline.icon
local iconCoords = treeline.iconCoords
@@ -60,7 +65,7 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
local value = treeline.value
local uniquevalue = treeline.uniquevalue
local disabled = treeline.disabled
-
+
button.treeline = treeline
button.value = value
button.uniquevalue = uniquevalue
@@ -71,6 +76,8 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
button:UnlockHighlight()
button.selected = false
end
+ local normalTexture = button:GetNormalTexture()
+ local line = button.line
button.level = level
if ( level == 1 ) then
button:SetNormalFontObject("GameFontNormal")
@@ -81,7 +88,7 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
button:SetHighlightFontObject("GameFontHighlightSmall")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
end
-
+
if disabled then
button:EnableMouse(false)
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
@@ -89,20 +96,20 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
button.text:SetText(text)
button:EnableMouse(true)
end
-
+
if icon then
button.icon:SetTexture(icon)
button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
else
button.icon:SetTexture(nil)
end
-
+
if iconCoords then
button.icon:SetTexCoord(unpack(iconCoords))
else
button.icon:SetTexCoord(0, 1, 0, 1)
end
-
+
if canExpand then
if not isExpanded then
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
@@ -155,7 +162,7 @@ end
local function FirstFrameUpdate(frame)
local self = frame.obj
frame:SetScript("OnUpdate", nil)
- self:RefreshTree(nil, true)
+ self:RefreshTree()
end
local function BuildUniqueValue(...)
@@ -192,6 +199,7 @@ end
local function Button_OnDoubleClick(button)
local self = button.obj
+ local status = self.status or self.localstatus
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
@@ -202,13 +210,11 @@ local function Button_OnEnter(frame)
self:Fire("OnButtonEnter", frame.uniquevalue, frame)
if self.enabletooltips then
- local tooltip = AceGUI.tooltip
- tooltip:SetOwner(frame, "ANCHOR_NONE")
- tooltip:ClearAllPoints()
- tooltip:SetPoint("LEFT",frame,"RIGHT")
- tooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1, true)
+ GameTooltip:SetOwner(frame, "ANCHOR_NONE")
+ GameTooltip:SetPoint("LEFT",frame,"RIGHT")
+ GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1)
- tooltip:Show()
+ GameTooltip:Show()
end
end
@@ -217,7 +223,7 @@ local function Button_OnLeave(frame)
self:Fire("OnButtonLeave", frame.uniquevalue, frame)
if self.enabletooltips then
- AceGUI.tooltip:Hide()
+ GameTooltip:Hide()
end
end
@@ -225,7 +231,7 @@ local function OnScrollValueChanged(frame, value)
if frame.obj.noupdate then return end
local self = frame.obj
local status = self.status or self.localstatus
- status.scrollvalue = floor(value + 0.5)
+ status.scrollvalue = value
self:RefreshTree()
AceGUI:ClearFocus()
end
@@ -263,19 +269,18 @@ end
local function Dragger_OnMouseUp(frame)
local treeframe = frame:GetParent()
local self = treeframe.obj
- local treeframeParent = treeframe:GetParent()
+ local frame = treeframe:GetParent()
treeframe:StopMovingOrSizing()
--treeframe:SetScript("OnUpdate", nil)
treeframe:SetUserPlaced(false)
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
treeframe:SetHeight(0)
- treeframe:ClearAllPoints()
- treeframe:SetPoint("TOPLEFT", treeframeParent, "TOPLEFT",0,0)
- treeframe:SetPoint("BOTTOMLEFT", treeframeParent, "BOTTOMLEFT",0,0)
-
+ treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
+ treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
+
local status = self.status or self.localstatus
status.treewidth = treeframe:GetWidth()
-
+
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
-- recalculate the content width
treeframe.obj:OnWidthSet(status.fullwidth)
@@ -290,13 +295,10 @@ local methods = {
["OnAcquire"] = function(self)
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
self:EnableButtonTooltips(true)
- self.frame:SetScript("OnUpdate", FirstFrameUpdate)
end,
["OnRelease"] = function(self)
self.status = nil
- self.tree = nil
- self.frame:SetScript("OnUpdate", nil)
for k, v in pairs(self.localstatus) do
if k == "groups" then
for k2 in pairs(v) do
@@ -333,8 +335,6 @@ local methods = {
button.toggle.button = button
button.toggle:SetScript("OnClick",Expand_OnClick)
- button.text:SetHeight(14) -- Prevents text wrapping
-
return button
end,
@@ -350,7 +350,7 @@ local methods = {
if not status.treewidth then
status.treewidth = DEFAULT_TREE_WIDTH
end
- if status.treesizable == nil then
+ if not status.treesizable then
status.treesizable = DEFAULT_TREE_SIZABLE
end
self:SetTreeWidth(status.treewidth,status.treesizable)
@@ -360,8 +360,8 @@ local methods = {
--sets the tree to be displayed
["SetTree"] = function(self, tree, filter)
self.filter = filter
- if tree then
- assert(type(tree) == "table")
+ if tree then
+ assert(type(tree) == "table")
end
self.tree = tree
self:RefreshTree()
@@ -369,7 +369,8 @@ local methods = {
["BuildLevel"] = function(self, tree, level, parent)
local groups = (self.status or self.localstatus).groups
-
+ local hasChildren = self.hasChildren
+
for i, v in ipairs(tree) do
if v.children then
if not self.filter or ShouldDisplayLevel(v.children) then
@@ -384,9 +385,13 @@ local methods = {
end
end,
- ["RefreshTree"] = function(self,scrollToSelection,fromOnUpdate)
- local buttons = self.buttons
+ ["RefreshTree"] = function(self)
+ local buttons = self.buttons
local lines = self.lines
+
+ for i, v in ipairs(buttons) do
+ v:Hide()
+ end
while lines[1] do
local t = tremove(lines)
for k in pairs(t) do
@@ -403,25 +408,14 @@ local methods = {
local treeframe = self.treeframe
- status.scrollToSelection = status.scrollToSelection or scrollToSelection -- needs to be cached in case the control hasn't been drawn yet (code bails out below)
-
self:BuildLevel(tree, 1)
local numlines = #lines
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
- if maxlines <= 0 then return end
-
- if self.frame:GetParent() == UIParent and not fromOnUpdate then
- self.frame:SetScript("OnUpdate", FirstFrameUpdate)
- return
- end
local first, last
- scrollToSelection = status.scrollToSelection
- status.scrollToSelection = nil
-
if numlines <= maxlines then
--the whole tree fits in the frame
status.scrollvalue = 0
@@ -435,34 +429,10 @@ local methods = {
--check if we are scrolled down too far
if numlines - status.scrollvalue < maxlines then
status.scrollvalue = numlines - maxlines
+ self.scrollbar:SetValue(status.scrollvalue)
end
self.noupdate = nil
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
- --show selection?
- if scrollToSelection and status.selected then
- local show
- for i,line in ipairs(lines) do -- find the line number
- if line.uniquevalue==status.selected then
- show=i
- end
- end
- if not show then
- -- selection was deleted or something?
- elseif show>=first and show<=last then
- -- all good
- else
- -- scrolling needed!
- if show 100 and status.treewidth > maxtreewidth then
self:SetTreeWidth(maxtreewidth, status.treesizable)
end
- if treeframe.SetResizeBounds then
- treeframe:SetResizeBounds(100, 1, maxtreewidth, 1600)
- else
- treeframe:SetMaxResize(maxtreewidth, 1600)
- end
+ treeframe:SetMaxResize(maxtreewidth, 1600)
end,
["OnHeightSet"] = function(self, height)
@@ -589,27 +549,22 @@ local methods = {
treewidth = DEFAULT_TREE_WIDTH
else
resizable = false
- treewidth = DEFAULT_TREE_WIDTH
+ treewidth = DEFAULT_TREE_WIDTH
end
end
self.treeframe:SetWidth(treewidth)
self.dragger:EnableMouse(resizable)
-
+
local status = self.status or self.localstatus
status.treewidth = treewidth
status.treesizable = resizable
-
+
-- recalculate the content width
if status.fullwidth then
self:OnWidthSet(status.fullwidth)
end
end,
- ["GetTreeWidth"] = function(self)
- local status = self.status or self.localstatus
- return status.treewidth or DEFAULT_TREE_WIDTH
- end,
-
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 20)
@@ -629,7 +584,7 @@ local PaneBackdrop = {
local DraggerBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = nil,
- tile = true, tileSize = 16, edgeSize = 1,
+ tile = true, tileSize = 16, edgeSize = 0,
insets = { left = 3, right = 3, top = 7, bottom = 7 }
}
@@ -637,7 +592,7 @@ local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
- local treeframe = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local treeframe = CreateFrame("Frame", nil, frame)
treeframe:SetPoint("TOPLEFT")
treeframe:SetPoint("BOTTOMLEFT")
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
@@ -646,17 +601,13 @@ local function Constructor()
treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
treeframe:SetResizable(true)
- if treeframe.SetResizeBounds then -- WoW 10.0
- treeframe:SetResizeBounds(100, 1, 400, 1600)
- else
- treeframe:SetMinResize(100, 1)
- treeframe:SetMaxResize(400, 1600)
- end
+ treeframe:SetMinResize(100, 1)
+ treeframe:SetMaxResize(400, 1600)
treeframe:SetScript("OnUpdate", FirstFrameUpdate)
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
- local dragger = CreateFrame("Frame", nil, treeframe, "BackdropTemplate")
+ local dragger = CreateFrame("Frame", nil, treeframe)
dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
@@ -679,9 +630,9 @@ local function Constructor()
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
- scrollbg:SetColorTexture(0,0,0,0.4)
+ scrollbg:SetTexture(0,0,0,0.4)
- local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local border = CreateFrame("Frame",nil,frame)
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
border:SetPoint("BOTTOMRIGHT")
border:SetBackdrop(PaneBackdrop)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
index 90af2e1..bb0a2a2 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
@@ -7,6 +7,10 @@ local pairs, assert, type = pairs, assert, type
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontNormal
+
----------------
-- Main Frame --
----------------
@@ -17,30 +21,26 @@ local CreateFrame, UIParent = CreateFrame, UIParent
]]
do
local Type = "Window"
- local Version = 8
-
- local function frameOnShow(this)
- this.obj:Fire("OnShow")
- end
+ local Version = 4
local function frameOnClose(this)
this.obj:Fire("OnClose")
end
-
+
local function closeOnClick(this)
- PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+ PlaySound("gsTitleOptionExit")
this.obj:Hide()
end
-
+
local function frameOnMouseDown(this)
AceGUI:ClearFocus()
end
-
+
local function titleOnMouseDown(this)
this:GetParent():StartMoving()
AceGUI:ClearFocus()
end
-
+
local function frameOnMouseUp(this)
local frame = this:GetParent()
frame:StopMovingOrSizing()
@@ -51,22 +51,22 @@ do
status.top = frame:GetTop()
status.left = frame:GetLeft()
end
-
+
local function sizerseOnMouseDown(this)
this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
-
+
local function sizersOnMouseDown(this)
this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
-
+
local function sizereOnMouseDown(this)
this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
-
+
local function sizerOnMouseUp(this)
this:GetParent():StopMovingOrSizing()
end
@@ -74,19 +74,19 @@ do
local function SetTitle(self,title)
self.titletext:SetText(title)
end
-
+
local function SetStatusText(self,text)
-- self.statustext:SetText(text)
end
-
+
local function Hide(self)
self.frame:Hide()
end
-
+
local function Show(self)
self.frame:Show()
end
-
+
local function OnAcquire(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
@@ -94,21 +94,21 @@ do
self:EnableResize(true)
self:Show()
end
-
+
local function OnRelease(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
-
+
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
self:ApplyStatus()
end
-
+
local function ApplyStatus(self)
local status = self.status or self.localstatus
local frame = self.frame
@@ -121,7 +121,7 @@ do
frame:SetPoint("CENTER",UIParent,"CENTER")
end
end
-
+
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 34
@@ -131,8 +131,8 @@ do
content:SetWidth(contentwidth)
content.width = contentwidth
end
-
-
+
+
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 57
@@ -142,19 +142,19 @@ do
content:SetHeight(contentheight)
content.height = contentheight
end
-
+
local function EnableResize(self, state)
local func = state and "Show" or "Hide"
self.sizer_se[func](self.sizer_se)
self.sizer_s[func](self.sizer_s)
self.sizer_e[func](self.sizer_e)
end
-
+
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = "Window"
-
+
self.Hide = Hide
self.Show = Show
self.SetTitle = SetTitle
@@ -166,9 +166,9 @@ do
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.EnableResize = EnableResize
-
+
self.localstatus = {}
-
+
self.frame = frame
frame.obj = self
frame:SetWidth(700)
@@ -179,95 +179,90 @@ do
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetScript("OnMouseDown", frameOnMouseDown)
-
- frame:SetScript("OnShow",frameOnShow)
+
frame:SetScript("OnHide",frameOnClose)
- if frame.SetResizeBounds then -- WoW 10.0
- frame:SetResizeBounds(240,240)
- else
- frame:SetMinResize(240,240)
- end
+ frame:SetMinResize(240,240)
frame:SetToplevel(true)
local titlebg = frame:CreateTexture(nil, "BACKGROUND")
- titlebg:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background")
+ titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]])
titlebg:SetPoint("TOPLEFT", 9, -6)
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
-
+
local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
- dialogbg:SetTexture("Interface\\Tooltips\\UI-Tooltip-Background")
+ dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
dialogbg:SetPoint("TOPLEFT", 8, -24)
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
dialogbg:SetVertexColor(0, 0, 0, .75)
-
+
local topleft = frame:CreateTexture(nil, "BORDER")
- topleft:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
topleft:SetWidth(64)
topleft:SetHeight(64)
topleft:SetPoint("TOPLEFT")
topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
-
+
local topright = frame:CreateTexture(nil, "BORDER")
- topright:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
topright:SetWidth(64)
topright:SetHeight(64)
topright:SetPoint("TOPRIGHT")
topright:SetTexCoord(0.625, 0.75, 0, 1)
-
+
local top = frame:CreateTexture(nil, "BORDER")
- top:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
top:SetHeight(64)
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
top:SetTexCoord(0.25, 0.369140625, 0, 1)
-
+
local bottomleft = frame:CreateTexture(nil, "BORDER")
- bottomleft:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottomleft:SetWidth(64)
bottomleft:SetHeight(64)
bottomleft:SetPoint("BOTTOMLEFT")
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
-
+
local bottomright = frame:CreateTexture(nil, "BORDER")
- bottomright:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottomright:SetWidth(64)
bottomright:SetHeight(64)
bottomright:SetPoint("BOTTOMRIGHT")
bottomright:SetTexCoord(0.875, 1, 0, 1)
-
+
local bottom = frame:CreateTexture(nil, "BORDER")
- bottom:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottom:SetHeight(64)
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
-
+
local left = frame:CreateTexture(nil, "BORDER")
- left:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
left:SetWidth(64)
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
left:SetTexCoord(0.001953125, 0.125, 0, 1)
-
+
local right = frame:CreateTexture(nil, "BORDER")
- right:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border")
+ right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
right:SetWidth(64)
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
-
+
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
close:SetPoint("TOPRIGHT", 2, 1)
close:SetScript("OnClick", closeOnClick)
self.closebutton = close
close.obj = self
-
+
local titletext = frame:CreateFontString(nil, "ARTWORK")
titletext:SetFontObject(GameFontNormal)
titletext:SetPoint("TOPLEFT", 12, -8)
titletext:SetPoint("TOPRIGHT", -32, -8)
self.titletext = titletext
-
+
local title = CreateFrame("Button", nil, frame)
title:SetPoint("TOPLEFT", titlebg)
title:SetPoint("BOTTOMRIGHT", titlebg)
@@ -275,7 +270,7 @@ do
title:SetScript("OnMouseDown",titleOnMouseDown)
title:SetScript("OnMouseUp", frameOnMouseUp)
self.title = title
-
+
local sizer_se = CreateFrame("Frame",nil,frame)
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
sizer_se:SetWidth(25)
@@ -300,7 +295,7 @@ do
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
- x = 0.1 * 8/17
+ local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame",nil,frame)
@@ -311,7 +306,7 @@ do
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_s = sizer_s
-
+
local sizer_e = CreateFrame("Frame",nil,frame)
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
@@ -320,17 +315,17 @@ do
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_e = sizer_e
-
+
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
-
+
AceGUI:RegisterAsContainer(self)
- return self
+ return self
end
-
+
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
index 0e286ca..2f49a01 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
@@ -2,7 +2,7 @@
Button Widget
Graphical Button.
-------------------------------------------------------------------------------]]
-local Type, Version = "Button", 24
+local Type, Version = "Button", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -17,9 +17,9 @@ local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
Scripts
-------------------------------------------------------------------------------]]
local function Button_OnClick(frame, ...)
- AceGUI:ClearFocus()
- PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
+ PlaySound("igMainMenuOption")
frame.obj:Fire("OnClick", ...)
+ AceGUI:ClearFocus()
end
local function Control_OnEnter(frame)
@@ -39,7 +39,6 @@ local methods = {
self:SetHeight(24)
self:SetWidth(200)
self:SetDisabled(false)
- self:SetAutoWidth(false)
self:SetText()
end,
@@ -47,16 +46,6 @@ local methods = {
["SetText"] = function(self, text)
self.text:SetText(text)
- if self.autoWidth then
- self:SetWidth(self.text:GetStringWidth() + 30)
- end
- end,
-
- ["SetAutoWidth"] = function(self, autoWidth)
- self.autoWidth = autoWidth
- if self.autoWidth then
- self:SetWidth(self.text:GetStringWidth() + 30)
- end
end,
["SetDisabled"] = function(self, disabled)
@@ -74,7 +63,7 @@ Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
- local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
+ local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate2")
frame:Hide()
frame:EnableMouse(true)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
index d03296d..34a2591 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
@@ -1,7 +1,7 @@
--[[-----------------------------------------------------------------------------
Checkbox Widget
-------------------------------------------------------------------------------]]
-local Type, Version = "CheckBox", 26
+local Type, Version = "CheckBox", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -12,6 +12,10 @@ local select, pairs = select, pairs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: SetDesaturation, GameFontHighlight
+
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
@@ -22,7 +26,7 @@ local function AlignImage(self)
self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
self.text:SetPoint("RIGHT")
else
- self.text:SetPoint("LEFT", self.image, "RIGHT", 1, 0)
+ self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0)
self.text:SetPoint("RIGHT")
end
end
@@ -56,9 +60,9 @@ local function CheckBox_OnMouseUp(frame)
self:ToggleChecked()
if self.checked then
- PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ PlaySound("igMainMenuOptionCheckBoxOn")
else -- for both nil and false (tristate)
- PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+ PlaySound("igMainMenuOptionCheckBoxOff")
end
self:Fire("OnValueChanged", self.checked)
@@ -87,7 +91,7 @@ local methods = {
if self.desc then
self.desc:SetWidth(width - 30)
if self.desc:GetText() and self.desc:GetText() ~= "" then
- self:SetHeight(28 + self.desc:GetStringHeight())
+ self:SetHeight(28 + self.desc:GetHeight())
end
end
end,
@@ -98,9 +102,6 @@ local methods = {
self.frame:Disable()
self.text:SetTextColor(0.5, 0.5, 0.5)
SetDesaturation(self.check, true)
- if self.desc then
- self.desc:SetTextColor(0.5, 0.5, 0.5)
- end
else
self.frame:Enable()
self.text:SetTextColor(1, 1, 1)
@@ -109,26 +110,23 @@ local methods = {
else
SetDesaturation(self.check, false)
end
- if self.desc then
- self.desc:SetTextColor(1, 1, 1)
- end
end
end,
- ["SetValue"] = function(self, value)
+ ["SetValue"] = function(self,value)
local check = self.check
self.checked = value
if value then
- SetDesaturation(check, false)
- check:Show()
+ SetDesaturation(self.check, false)
+ self.check:Show()
else
--Nil is the unknown tristate value
if self.tristate and value == nil then
- SetDesaturation(check, true)
- check:Show()
+ SetDesaturation(self.check, true)
+ self.check:Show()
else
- SetDesaturation(check, false)
- check:Hide()
+ SetDesaturation(self.check, false)
+ self.check:Hide()
end
end
self:SetDisabled(self.disabled)
@@ -195,19 +193,18 @@ local methods = {
["SetDescription"] = function(self, desc)
if desc then
if not self.desc then
- local f = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
- f:ClearAllPoints()
- f:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
- f:SetWidth(self.frame.width - 30)
- f:SetPoint("RIGHT", self.frame, "RIGHT", -30, 0)
- f:SetJustifyH("LEFT")
- f:SetJustifyV("TOP")
- self.desc = f
+ local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ desc:ClearAllPoints()
+ desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
+ desc:SetWidth(self.frame.width - 30)
+ desc:SetJustifyH("LEFT")
+ desc:SetJustifyV("TOP")
+ self.desc = desc
end
self.desc:Show()
--self.text:SetFontObject(GameFontNormal)
self.desc:SetText(desc)
- self:SetHeight(28 + self.desc:GetStringHeight())
+ self:SetHeight(28 + self.desc:GetHeight())
else
if self.desc then
self.desc:SetText("")
@@ -217,11 +214,11 @@ local methods = {
self:SetHeight(24)
end
end,
-
+
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
-
+
if image:GetTexture() then
local n = select("#", ...)
if n == 4 or n == 8 then
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
index a8aeca5..ba02615 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
@@ -1,7 +1,7 @@
--[[-----------------------------------------------------------------------------
ColorPicker Widget
-------------------------------------------------------------------------------]]
-local Type, Version = "ColorPicker", 28
+local Type, Version = "ColorPicker", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -11,24 +11,17 @@ local pairs = pairs
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
--- Unfortunately we have no way to realistically detect if a client uses inverted alpha
--- as no API will tell you. Wrath uses the old colorpicker, era uses the new one, both are inverted
-local INVERTED_ALPHA = (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE)
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function ColorCallback(self, r, g, b, a, isAlpha)
- if INVERTED_ALPHA and a then
- a = 1 - a
- end
if not self.HasAlpha then
a = 1
end
- -- no change, skip update
- if r == self.r and g == self.g and b == self.b and a == self.a then
- return
- end
self:SetColor(r, g, b, a)
if ColorPickerFrame:IsVisible() then
--colorpicker is still open
@@ -54,70 +47,35 @@ local function Control_OnLeave(frame)
end
local function ColorSwatch_OnClick(frame)
- ColorPickerFrame:Hide()
+ HideUIPanel(ColorPickerFrame)
local self = frame.obj
if not self.disabled then
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
- ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
- ColorPickerFrame:SetClampedToScreen(true)
- if ColorPickerFrame.SetupColorPickerAndShow then -- 10.2.5 color picker overhaul
- local r2, g2, b2, a2 = self.r, self.g, self.b, (self.a or 1)
- if INVERTED_ALPHA then
- a2 = 1 - a2
- end
-
- local info = {
- swatchFunc = function()
- local r, g, b = ColorPickerFrame:GetColorRGB()
- local a = ColorPickerFrame:GetColorAlpha()
- ColorCallback(self, r, g, b, a)
- end,
-
- hasOpacity = self.HasAlpha,
- opacityFunc = function()
- local r, g, b = ColorPickerFrame:GetColorRGB()
- local a = ColorPickerFrame:GetColorAlpha()
- ColorCallback(self, r, g, b, a, true)
- end,
- opacity = a2,
-
- cancelFunc = function()
- ColorCallback(self, r2, g2, b2, a2, true)
- end,
-
- r = r2,
- g = g2,
- b = b2,
- }
-
- ColorPickerFrame:SetupColorPickerAndShow(info)
- else
- ColorPickerFrame.func = function()
- local r, g, b = ColorPickerFrame:GetColorRGB()
- local a = OpacitySliderFrame:GetValue()
- ColorCallback(self, r, g, b, a)
- end
-
- ColorPickerFrame.hasOpacity = self.HasAlpha
- ColorPickerFrame.opacityFunc = function()
- local r, g, b = ColorPickerFrame:GetColorRGB()
- local a = OpacitySliderFrame:GetValue()
- ColorCallback(self, r, g, b, a, true)
- end
-
- local r, g, b, a = self.r, self.g, self.b, 1 - (self.a or 1)
- if self.HasAlpha then
- ColorPickerFrame.opacity = a
- end
- ColorPickerFrame:SetColorRGB(r, g, b)
-
- ColorPickerFrame.cancelFunc = function()
- ColorCallback(self, r, g, b, a, true)
- end
-
- ColorPickerFrame:Show()
+ ColorPickerFrame.func = function()
+ local r, g, b = ColorPickerFrame:GetColorRGB()
+ local a = 1 - OpacitySliderFrame:GetValue()
+ ColorCallback(self, r, g, b, a)
end
+
+ ColorPickerFrame.hasOpacity = self.HasAlpha
+ ColorPickerFrame.opacityFunc = function()
+ local r, g, b = ColorPickerFrame:GetColorRGB()
+ local a = 1 - OpacitySliderFrame:GetValue()
+ ColorCallback(self, r, g, b, a, true)
+ end
+
+ local r, g, b, a = self.r, self.g, self.b, self.a
+ if self.HasAlpha then
+ ColorPickerFrame.opacity = 1 - (a or 0)
+ end
+ ColorPickerFrame:SetColorRGB(r, g, b)
+
+ ColorPickerFrame.cancelFunc = function()
+ ColorCallback(self, r, g, b, a, true)
+ end
+
+ ShowUIPanel(ColorPickerFrame)
end
AceGUI:ClearFocus()
end
@@ -184,15 +142,13 @@ local function Constructor()
colorSwatch:SetPoint("LEFT")
local texture = frame:CreateTexture(nil, "BACKGROUND")
- colorSwatch.background = texture
texture:SetWidth(16)
texture:SetHeight(16)
- texture:SetColorTexture(1, 1, 1)
+ texture:SetTexture(1, 1, 1)
texture:SetPoint("CENTER", colorSwatch)
texture:Show()
local checkers = frame:CreateTexture(nil, "BACKGROUND")
- colorSwatch.checkers = checkers
checkers:SetWidth(14)
checkers:SetHeight(14)
checkers:SetTexture("Tileset\\Generic\\Checkers")
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
index a737697..37baf04 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
@@ -1,4 +1,4 @@
---[[ $Id$ ]]--
+--[[ $Id: AceGUIWidget-DropDown-Items.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
local AceGUI = LibStub("AceGUI-3.0")
@@ -33,7 +33,7 @@ end
-- ItemBase is the base "class" for all dropdown items.
-- Each item has to use ItemBase.Create(widgetType) to
--- create an initial 'self' value.
+-- create an initial 'self' value.
-- ItemBase will add common functions and ui event handlers.
-- Be sure to keep basic usage when you override functions.
@@ -41,7 +41,7 @@ local ItemBase = {
-- NOTE: The ItemBase version is added to each item's version number
-- to ensure proper updates on ItemBase changes.
-- Use at least 1000er steps.
- version = 2000,
+ version = 1000,
counter = 0,
}
@@ -52,7 +52,7 @@ function ItemBase.Frame_OnEnter(this)
self.highlight:Show()
end
self:Fire("OnEnter")
-
+
if self.specialOnEnter then
self.specialOnEnter(self)
end
@@ -60,10 +60,10 @@ end
function ItemBase.Frame_OnLeave(this)
local self = this.obj
-
+
self.highlight:Hide()
self:Fire("OnLeave")
-
+
if self.specialOnLeave then
self.specialOnLeave(self)
end
@@ -89,7 +89,7 @@ end
-- Do not call this method directly
function ItemBase.SetPullout(self, pullout)
self.pullout = pullout
-
+
self.frame:SetParent(nil)
self.frame:SetParent(pullout.itemFrame)
self.parent = pullout.itemFrame
@@ -155,12 +155,12 @@ function ItemBase.Create(type)
self.frame = frame
frame.obj = self
self.type = type
-
+
self.useHighlight = true
-
+
frame:SetHeight(17)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
-
+
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
text:SetTextColor(1,1,1)
text:SetJustifyH("LEFT")
@@ -178,7 +178,7 @@ function ItemBase.Create(type)
highlight:Hide()
self.highlight = highlight
- local check = frame:CreateTexture(nil, "OVERLAY")
+ local check = frame:CreateTexture("OVERLAY")
check:SetWidth(16)
check:SetHeight(16)
check:SetPoint("LEFT",frame,"LEFT",3,-1)
@@ -186,57 +186,51 @@ function ItemBase.Create(type)
check:Hide()
self.check = check
- local sub = frame:CreateTexture(nil, "OVERLAY")
+ local sub = frame:CreateTexture("OVERLAY")
sub:SetWidth(16)
sub:SetHeight(16)
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
sub:Hide()
- self.sub = sub
-
+ self.sub = sub
+
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
-
+
self.OnAcquire = ItemBase.OnAcquire
self.OnRelease = ItemBase.OnRelease
-
+
self.SetPullout = ItemBase.SetPullout
self.GetText = ItemBase.GetText
self.SetText = ItemBase.SetText
self.SetDisabled = ItemBase.SetDisabled
-
+
self.SetPoint = ItemBase.SetPoint
self.Show = ItemBase.Show
self.Hide = ItemBase.Hide
-
+
self.SetOnLeave = ItemBase.SetOnLeave
self.SetOnEnter = ItemBase.SetOnEnter
-
+
return self
end
--- Register a dummy LibStub library to retrieve the ItemBase, so other addons can use it.
-local IBLib = LibStub:NewLibrary("AceGUI-3.0-DropDown-ItemBase", ItemBase.version)
-if IBLib then
- IBLib.GetItemBase = function() return ItemBase end
-end
-
--[[
Template for items:
-
+
-- Item:
--
do
local widgetType = "Dropdown-Item-"
local widgetVersion = 1
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
--]]
@@ -247,25 +241,25 @@ end
do
local widgetType = "Dropdown-Item-Header"
local widgetVersion = 1
-
+
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
-
+
if self.specialOnEnter then
self.specialOnEnter(self)
end
end
-
+
local function OnLeave(this)
local self = this.obj
self:Fire("OnLeave")
-
+
if self.specialOnLeave then
self.specialOnLeave(self)
end
end
-
+
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
@@ -273,21 +267,21 @@ do
self.text:SetTextColor(1, 1, 0)
end
end
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
self.SetDisabled = SetDisabled
-
+
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnLeave", OnLeave)
-
+
self.text:SetTextColor(1, 1, 0)
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
@@ -296,7 +290,7 @@ end
do
local widgetType = "Dropdown-Item-Execute"
local widgetVersion = 1
-
+
local function Frame_OnClick(this, button)
local self = this.obj
if self.disabled then return end
@@ -305,16 +299,16 @@ do
self.pullout:Close()
end
end
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
self.frame:SetScript("OnClick", Frame_OnClick)
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
@@ -323,8 +317,8 @@ end
-- Does not close the pullout on click.
do
local widgetType = "Dropdown-Item-Toggle"
- local widgetVersion = 4
-
+ local widgetVersion = 3
+
local function UpdateToggle(self)
if self.value then
self.check:Show()
@@ -332,49 +326,49 @@ do
self.check:Hide()
end
end
-
+
local function OnRelease(self)
ItemBase.OnRelease(self)
self:SetValue(nil)
end
-
+
local function Frame_OnClick(this, button)
local self = this.obj
if self.disabled then return end
self.value = not self.value
if self.value then
- PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ PlaySound("igMainMenuOptionCheckBoxOn")
else
- PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+ PlaySound("igMainMenuOptionCheckBoxOff")
end
UpdateToggle(self)
self:Fire("OnValueChanged", self.value)
end
-
+
-- exported
local function SetValue(self, value)
self.value = value
UpdateToggle(self)
end
-
+
-- exported
local function GetValue(self)
return self.value
end
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
self.frame:SetScript("OnClick", Frame_OnClick)
-
+
self.SetValue = SetValue
self.GetValue = GetValue
self.OnRelease = OnRelease
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
@@ -384,55 +378,55 @@ end
do
local widgetType = "Dropdown-Item-Menu"
local widgetVersion = 2
-
+
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
-
+
if self.specialOnEnter then
self.specialOnEnter(self)
end
-
+
self.highlight:Show()
-
+
if not self.disabled and self.submenu then
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
end
end
-
+
local function OnHide(this)
local self = this.obj
if self.submenu then
self.submenu:Close()
end
end
-
+
-- exported
local function SetMenu(self, menu)
assert(menu.type == "Dropdown-Pullout")
self.submenu = menu
end
-
+
-- exported
local function CloseMenu(self)
self.submenu:Close()
end
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
self.sub:Show()
-
+
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnHide", OnHide)
-
+
self.SetMenu = SetMenu
self.CloseMenu = CloseMenu
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
@@ -440,32 +434,32 @@ end
-- A single line to separate items
do
local widgetType = "Dropdown-Item-Separator"
- local widgetVersion = 2
-
+ local widgetVersion = 1
+
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
self.useHighlight = false
end
-
+
local function Constructor()
local self = ItemBase.Create(widgetType)
-
+
self.SetDisabled = SetDisabled
-
+
local line = self.frame:CreateTexture(nil, "OVERLAY")
line:SetHeight(1)
- line:SetColorTexture(.5, .5, .5)
+ line:SetTexture(.5, .5, .5)
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
-
+
self.text:Hide()
-
+
self.useHighlight = false
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
index 9fde707..cbbba1a 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
@@ -1,9 +1,9 @@
---[[ $Id$ ]]--
+--[[ $Id: AceGUIWidget-DropDown.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local min, max, floor = math.min, math.max, math.floor
-local select, pairs, ipairs, type, tostring = select, pairs, ipairs, type, tostring
+local select, pairs, ipairs = select, pairs, ipairs
local tsort = table.sort
-- WoW APIs
@@ -11,6 +11,10 @@ local PlaySound = PlaySound
local UIParent, CreateFrame = UIParent, CreateFrame
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
local function fixlevels(parent,...)
local i = 1
local child = select(i, ...)
@@ -35,10 +39,10 @@ end
do
local widgetType = "Dropdown-Pullout"
- local widgetVersion = 5
-
+ local widgetVersion = 3
+
--[[ Static data ]]--
-
+
local backdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
@@ -56,9 +60,9 @@ do
local defaultWidth = 200
local defaultMaxHeight = 600
-
+
--[[ UI Event Handlers ]]--
-
+
-- HACK: This should be no part of the pullout, but there
-- is no other 'clean' way to response to any item-OnEnter
-- Used to close Submenus when an other item is entered
@@ -70,22 +74,22 @@ do
end
end
end
-
+
-- See the note in Constructor() for each scroll related function
local function OnMouseWheel(this, value)
this.obj:MoveScroll(value)
end
-
+
local function OnScrollValueChanged(this, value)
this.obj:SetScroll(value)
end
-
+
local function OnSizeChanged(this)
this.obj:FixScroll()
end
-
+
--[[ Exported methods ]]--
-
+
-- exported
local function SetScroll(self, value)
local status = self.scrollStatus
@@ -102,9 +106,9 @@ do
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
status.offset = offset
- status.scrollvalue = value
+ status.scrollvalue = value
end
-
+
-- exported
local function MoveScroll(self, value)
local status = self.scrollStatus
@@ -123,7 +127,7 @@ do
self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
end
end
-
+
-- exported
local function FixScroll(self)
local status = self.scrollStatus
@@ -136,7 +140,7 @@ do
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
self.slider:SetValue(0)
else
- self.slider:Show()
+ self.slider:Show()
local value = (offset / (viewheight - height) * 1000)
if value > 1000 then value = 1000 end
self.slider:SetValue(value)
@@ -149,63 +153,68 @@ do
end
end
end
-
+
-- exported, AceGUI callback
local function OnAcquire(self)
self.frame:SetParent(UIParent)
--self.itemFrame:SetToplevel(true)
end
-
+
-- exported, AceGUI callback
local function OnRelease(self)
self:Clear()
self.frame:ClearAllPoints()
self.frame:Hide()
end
-
+
-- exported
local function AddItem(self, item)
self.items[#self.items + 1] = item
-
+
local h = #self.items * 16
self.itemFrame:SetHeight(h)
self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
-
+
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
-
+
item:SetPullout(self)
item:SetOnEnter(OnEnter)
end
-
+
-- exported
- local function Open(self, point, relFrame, relPoint, x, y)
+ local function Open(self, point, relFrame, relPoint, x, y)
local items = self.items
local frame = self.frame
local itemFrame = self.itemFrame
-
+
frame:SetPoint(point, relFrame, relPoint, x, y)
-
+
local height = 8
for i, item in pairs(items) do
- item:SetPoint("TOP", itemFrame, "TOP", 0, -2 + (i - 1) * -16)
+ if i == 1 then
+ item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
+ else
+ item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
+ end
+
item:Show()
-
+
height = height + 16
end
itemFrame:SetHeight(height)
fixstrata("TOOLTIP", frame, frame:GetChildren())
frame:Show()
self:Fire("OnOpen")
- end
-
+ end
+
-- exported
local function Close(self)
self.frame:Hide()
self:Fire("OnClose")
- end
-
+ end
+
-- exported
local function Clear(self)
local items = self.items
@@ -213,18 +222,18 @@ do
AceGUI:Release(item)
items[i] = nil
end
- end
-
+ end
+
-- exported
local function IterateItems(self)
return ipairs(self.items)
end
-
+
-- exported
local function SetHideOnLeave(self, val)
self.hideOnLeave = val
end
-
+
-- exported
local function SetMaxHeight(self, height)
self.maxHeight = height or defaultMaxHeight
@@ -234,28 +243,28 @@ do
self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
end
end
-
+
-- exported
local function GetRightBorderWidth(self)
return 6 + (self.slider:IsShown() and 12 or 0)
end
-
+
-- exported
local function GetLeftBorderWidth(self)
return 6
end
-
+
--[[ Constructor ]]--
-
+
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
- local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent, "BackdropTemplate")
+ local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
local self = {}
self.count = count
self.type = widgetType
self.frame = frame
frame.obj = self
-
+
self.OnAcquire = OnAcquire
self.OnRelease = OnRelease
@@ -269,38 +278,38 @@ do
self.SetScroll = SetScroll
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
-
+
self.SetMaxHeight = SetMaxHeight
self.GetRightBorderWidth = GetRightBorderWidth
self.GetLeftBorderWidth = GetLeftBorderWidth
-
+
self.items = {}
-
+
self.scrollStatus = {
scrollvalue = 0,
}
-
+
self.maxHeight = defaultMaxHeight
-
+
frame:SetBackdrop(backdrop)
frame:SetBackdropColor(0, 0, 0)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetClampedToScreen(true)
frame:SetWidth(defaultWidth)
- frame:SetHeight(self.maxHeight)
+ frame:SetHeight(self.maxHeight)
--frame:SetToplevel(true)
-
+
-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
local itemFrame = CreateFrame("Frame", nil, scrollFrame)
-
+
self.scrollFrame = scrollFrame
self.itemFrame = itemFrame
-
+
scrollFrame.obj = self
itemFrame.obj = self
-
- local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame, "BackdropTemplate")
+
+ local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
slider:SetOrientation("VERTICAL")
slider:SetHitRectInsets(0, 0, -10, 0)
slider:SetBackdrop(sliderBackdrop)
@@ -309,7 +318,7 @@ do
slider:SetFrameStrata("FULLSCREEN_DIALOG")
self.slider = slider
slider.obj = self
-
+
scrollFrame:SetScrollChild(itemFrame)
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
@@ -318,48 +327,46 @@ do
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
scrollFrame:SetToplevel(true)
scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
-
+
itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
itemFrame:SetHeight(400)
itemFrame:SetToplevel(true)
itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
-
+
slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
slider:SetScript("OnValueChanged", OnScrollValueChanged)
slider:SetMinMaxValues(0, 1000)
slider:SetValueStep(1)
slider:SetValue(0)
-
+
scrollFrame:Show()
itemFrame:Show()
slider:Hide()
-
+
self:FixScroll()
-
+
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
end
do
local widgetType = "Dropdown"
- local widgetVersion = 36
-
+ local widgetVersion = 22
+
--[[ Static data ]]--
-
+
--[[ UI event handler ]]--
-
+
local function Control_OnEnter(this)
- this.obj.button:LockHighlight()
this.obj:Fire("OnEnter")
end
-
+
local function Control_OnLeave(this)
- this.obj.button:UnlockHighlight()
this.obj:Fire("OnLeave")
end
@@ -369,33 +376,33 @@ do
self.pullout:Close()
end
end
-
+
local function Dropdown_TogglePullout(this)
local self = this.obj
+ PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
if self.open then
self.open = nil
self.pullout:Close()
AceGUI:ClearFocus()
else
self.open = true
- self.pullout:SetWidth(self.pulloutWidth or self.frame:GetWidth())
+ self.pullout:SetWidth(self.frame:GetWidth())
self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
AceGUI:SetFocus(self)
end
end
-
+
local function OnPulloutOpen(this)
local self = this.userdata.obj
local value = self.value
-
+
if not self.multiselect then
for i, item in this:IterateItems() do
item:SetValue(item.userdata.value == value)
end
end
-
+
self.open = true
- self:Fire("OnOpened")
end
local function OnPulloutClose(this)
@@ -403,7 +410,7 @@ do
self.open = nil
self:Fire("OnClosed")
end
-
+
local function ShowMultiText(self)
local text
for i, widget in self.pullout:IterateItems() do
@@ -419,10 +426,10 @@ do
end
self:SetText(text)
end
-
+
local function OnItemValueChanged(this, event, checked)
local self = this.userdata.obj
-
+
if self.multiselect then
self:Fire("OnValueChanged", this.userdata.value, checked)
ShowMultiText(self)
@@ -433,14 +440,14 @@ do
else
this:SetValue(true)
end
- if self.open then
+ if self.open then
self.pullout:Close()
end
end
end
-
+
--[[ Exported methods ]]--
-
+
-- exported, AceGUI callback
local function OnAcquire(self)
local pullout = AceGUI:Create("Dropdown-Pullout")
@@ -450,14 +457,11 @@ do
pullout:SetCallback("OnOpen", OnPulloutOpen)
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
-
+
self:SetHeight(44)
self:SetWidth(200)
- self:SetLabel()
- self:SetPulloutWidth(nil)
- self.list = {}
end
-
+
-- exported, AceGUI callback
local function OnRelease(self)
if self.open then
@@ -465,76 +469,75 @@ do
end
AceGUI:Release(self.pullout)
self.pullout = nil
-
+
self:SetText("")
+ self:SetLabel("")
self:SetDisabled(false)
self:SetMultiselect(false)
-
+
self.value = nil
self.list = nil
self.open = nil
self.hasClose = nil
-
+
self.frame:ClearAllPoints()
self.frame:Hide()
end
-
+
-- exported
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.text:SetTextColor(0.5,0.5,0.5)
self.button:Disable()
- self.button_cover:Disable()
self.label:SetTextColor(0.5,0.5,0.5)
else
self.button:Enable()
- self.button_cover:Enable()
self.label:SetTextColor(1,.82,0)
self.text:SetTextColor(1,1,1)
end
end
-
+
-- exported
local function ClearFocus(self)
if self.open then
self.pullout:Close()
end
end
-
+
-- exported
local function SetText(self, text)
self.text:SetText(text or "")
end
-
+
-- exported
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
- self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-14)
- self:SetHeight(40)
- self.alignoffset = 26
+ self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-18)
+ self.frame:SetHeight(44)
else
self.label:SetText("")
self.label:Hide()
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
- self:SetHeight(26)
- self.alignoffset = 12
+ self.frame:SetHeight(26)
end
end
-
+
-- exported
local function SetValue(self, value)
- self:SetText(self.list[value] or "")
+ if self.list then
+ self:SetText(self.list[value] or "")
+ end
self.value = value
end
-
+
-- exported
local function GetValue(self)
return self.value
end
-
+
-- exported
local function SetItemValue(self, item, value)
if not self.multiselect then return end
@@ -547,7 +550,7 @@ do
end
ShowMultiText(self)
end
-
+
-- exported
local function SetItemDisabled(self, item, disabled)
for i, widget in self.pullout:IterateItems() do
@@ -556,20 +559,16 @@ do
end
end
end
-
- local function AddListItem(self, value, text, itemType)
- if not itemType then itemType = "Dropdown-Item-Toggle" end
- local exists = AceGUI:GetWidgetVersion(itemType)
- if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
-
- local item = AceGUI:Create(itemType)
+
+ local function AddListItem(self, value, text)
+ local item = AceGUI:Create("Dropdown-Item-Toggle")
item:SetText(text)
item.userdata.obj = self
item.userdata.value = value
item:SetCallback("OnValueChanged", OnItemValueChanged)
self.pullout:AddItem(item)
end
-
+
local function AddCloseButton(self)
if not self.hasClose then
local close = AceGUI:Create("Dropdown-Item-Execute")
@@ -578,50 +577,38 @@ do
self.hasClose = true
end
end
-
+
-- exported
local sortlist = {}
- local function sortTbl(x,y)
- local num1, num2 = tonumber(x), tonumber(y)
- if num1 and num2 then -- numeric comparison, either two numbers or numeric strings
- return num1 < num2
- else -- compare everything else tostring'ed
- return tostring(x) < tostring(y)
- end
- end
- local function SetList(self, list, order, itemType)
- self.list = list or {}
+ local function SetList(self, list)
+ self.list = list
self.pullout:Clear()
self.hasClose = nil
if not list then return end
-
- if type(order) ~= "table" then
- for v in pairs(list) do
- sortlist[#sortlist + 1] = v
- end
- tsort(sortlist, sortTbl)
-
- for i, key in ipairs(sortlist) do
- AddListItem(self, key, list[key], itemType)
- sortlist[i] = nil
- end
- else
- for i, key in ipairs(order) do
- AddListItem(self, key, list[key], itemType)
- end
+
+ for v in pairs(list) do
+ sortlist[#sortlist + 1] = v
+ end
+ tsort(sortlist)
+
+ for i, value in pairs(sortlist) do
+ AddListItem(self, value, list[value])
+ sortlist[i] = nil
end
if self.multiselect then
ShowMultiText(self)
AddCloseButton(self)
end
end
-
+
-- exported
- local function AddItem(self, value, text, itemType)
- self.list[value] = text
- AddListItem(self, value, text, itemType)
+ local function AddItem(self, value, text)
+ if self.list then
+ self.list[value] = text
+ AddListItem(self, value, text)
+ end
end
-
+
-- exported
local function SetMultiselect(self, multi)
self.multiselect = multi
@@ -630,23 +617,19 @@ do
AddCloseButton(self)
end
end
-
+
-- exported
local function GetMultiselect(self)
return self.multiselect
end
-
- local function SetPulloutWidth(self, width)
- self.pulloutWidth = width
- end
-
+
--[[ Constructor ]]--
-
+
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", nil, UIParent)
local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
-
+
local self = {}
self.type = widgetType
self.frame = frame
@@ -654,10 +637,10 @@ do
self.count = count
frame.obj = self
dropdown.obj = self
-
+
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
-
+
self.ClearFocus = ClearFocus
self.SetText = SetText
@@ -671,10 +654,11 @@ do
self.GetMultiselect = GetMultiselect
self.SetItemValue = SetItemValue
self.SetItemDisabled = SetItemDisabled
- self.SetPulloutWidth = SetPulloutWidth
-
- self.alignoffset = 26
-
+
+ self.alignoffset = 31
+
+ frame:SetHeight(44)
+ frame:SetWidth(200)
frame:SetScript("OnHide",Dropdown_OnHide)
dropdown:ClearAllPoints()
@@ -685,10 +669,10 @@ do
local left = _G[dropdown:GetName() .. "Left"]
local middle = _G[dropdown:GetName() .. "Middle"]
local right = _G[dropdown:GetName() .. "Right"]
-
+
middle:ClearAllPoints()
right:ClearAllPoints()
-
+
middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
@@ -699,23 +683,14 @@ do
button:SetScript("OnEnter",Control_OnEnter)
button:SetScript("OnLeave",Control_OnLeave)
button:SetScript("OnClick",Dropdown_TogglePullout)
-
- local button_cover = CreateFrame("BUTTON",nil,self.frame)
- self.button_cover = button_cover
- button_cover.obj = self
- button_cover:SetPoint("TOPLEFT",self.frame,"BOTTOMLEFT",0,25)
- button_cover:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT")
- button_cover:SetScript("OnEnter",Control_OnEnter)
- button_cover:SetScript("OnLeave",Control_OnLeave)
- button_cover:SetScript("OnClick",Dropdown_TogglePullout)
-
+
local text = _G[dropdown:GetName() .. "Text"]
self.text = text
text.obj = self
text:ClearAllPoints()
text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
text:SetPoint("LEFT", left, "LEFT", 25, 2)
-
+
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
@@ -727,6 +702,6 @@ do
AceGUI:RegisterAsWidget(self)
return self
end
-
+
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
-end
+end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
index ae1e969..34a2958 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
@@ -1,7 +1,7 @@
--[[-----------------------------------------------------------------------------
EditBox Widget
-------------------------------------------------------------------------------]]
-local Type, Version = "EditBox", 29
+local Type, Version = "EditBox", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -10,20 +10,20 @@ local tostring, pairs = tostring, pairs
-- WoW APIs
local PlaySound = PlaySound
-local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
+local GetCursorInfo, ClearCursor, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
+
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
if not AceGUIEditBoxInsertLink then
-- upgradeable hook
- if ChatFrameUtil and ChatFrameUtil.InsertLink then
- hooksecurefunc(ChatFrameUtil, "InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
- elseif ChatEdit_InsertLink then
- hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
- end
+ hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
end
function _G.AceGUIEditBoxInsertLink(text)
@@ -59,11 +59,6 @@ local function Control_OnLeave(frame)
frame.obj:Fire("OnLeave")
end
-local function Frame_OnShowFocus(frame)
- frame.obj.editbox:SetFocus()
- frame:SetScript("OnShow", nil)
-end
-
local function EditBox_OnEscapePressed(frame)
AceGUI:ClearFocus()
end
@@ -73,33 +68,29 @@ local function EditBox_OnEnterPressed(frame)
local value = frame:GetText()
local cancel = self:Fire("OnEnterPressed", value)
if not cancel then
- PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ PlaySound("igMainMenuOptionCheckBoxOn")
HideButton(self)
end
end
local function EditBox_OnReceiveDrag(frame)
local self = frame.obj
- local type, id, info, extra = GetCursorInfo()
- local name
+ local type, id, info = GetCursorInfo()
if type == "item" then
- name = info
+ self:SetText(info)
+ self:Fire("OnEnterPressed", info)
+ ClearCursor()
elseif type == "spell" then
- if C_Spell and C_Spell.GetSpellName then
- name = C_Spell.GetSpellName(extra)
- else
- name = GetSpellInfo(id, info)
+ local name, rank = GetSpellName(id, info)
+ if rank and rank:match("%d") then
+ name = name.."("..rank..")"
end
- elseif type == "macro" then
- name = GetMacroInfo(id)
- end
- if name then
self:SetText(name)
self:Fire("OnEnterPressed", name)
ClearCursor()
- HideButton(self)
- AceGUI:ClearFocus()
end
+ HideButton(self)
+ AceGUI:ClearFocus()
end
local function EditBox_OnTextChanged(frame)
@@ -112,10 +103,6 @@ local function EditBox_OnTextChanged(frame)
end
end
-local function EditBox_OnFocusGained(frame)
- AceGUI:SetFocus(frame.obj)
-end
-
local function Button_OnClick(frame)
local editbox = frame.obj.editbox
editbox:ClearFocus()
@@ -136,9 +123,7 @@ local methods = {
self:SetMaxLetters(0)
end,
- ["OnRelease"] = function(self)
- self:ClearFocus()
- end,
+ -- ["OnRelease"] = nil,
["SetDisabled"] = function(self, disabled)
self.disabled = disabled
@@ -190,22 +175,6 @@ local methods = {
["SetMaxLetters"] = function (self, num)
self.editbox:SetMaxLetters(num or 0)
- end,
-
- ["ClearFocus"] = function(self)
- self.editbox:ClearFocus()
- self.frame:SetScript("OnShow", nil)
- end,
-
- ["SetFocus"] = function(self)
- self.editbox:SetFocus()
- if not self.frame:IsShown() then
- self.frame:SetScript("OnShow", Frame_OnShowFocus)
- end
- end,
-
- ["HighlightText"] = function(self, from, to)
- self.editbox:HighlightText(from, to)
end
}
@@ -227,7 +196,6 @@ local function Constructor()
editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
- editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
editbox:SetTextInsets(0, 0, 3, 3)
editbox:SetMaxLetters(256)
editbox:SetPoint("BOTTOMLEFT", 6, 0)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
index 94d6774..f25b586 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
@@ -1,7 +1,7 @@
--[[-----------------------------------------------------------------------------
Icon Widget
-------------------------------------------------------------------------------]]
-local Type, Version = "Icon", 21
+local Type, Version = "Icon", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -9,7 +9,7 @@ if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local select, pairs, print = select, pairs, print
-- WoW APIs
-local CreateFrame, UIParent = CreateFrame, UIParent
+local CreateFrame, UIParent, GetBuildInfo = CreateFrame, UIParent, GetBuildInfo
--[[-----------------------------------------------------------------------------
Scripts
@@ -56,7 +56,7 @@ local methods = {
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
-
+
if image:GetTexture() then
local n = select("#", ...)
if n == 4 or n == 8 then
@@ -87,7 +87,7 @@ local methods = {
else
self.frame:Enable()
self.label:SetTextColor(1, 1, 1)
- self.image:SetVertexColor(1, 1, 1, 1)
+ self.image:SetVertexColor(1, 1, 1)
end
end
}
@@ -131,8 +131,12 @@ local function Constructor()
for method, func in pairs(methods) do
widget[method] = func
end
-
- widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
+ -- SetText is deprecated, but keep it around for a while. (say, to WoW 4.0)
+ if (select(4, GetBuildInfo()) < 40000) then
+ widget.SetText = widget.SetLabel
+ else
+ widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
+ end
return AceGUI:RegisterAsWidget(widget)
end
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
index 255dd97..9e06049 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
@@ -1,13 +1,20 @@
--[[-----------------------------------------------------------------------------
InteractiveLabel Widget
-------------------------------------------------------------------------------]]
-local Type, Version = "InteractiveLabel", 21
+local Type, Version = "InteractiveLabel", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local select, pairs = select, pairs
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
index 07c8f76..f3043ff 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
@@ -2,7 +2,7 @@
Keybinding Widget
Set Keybindings in the Config UI.
-------------------------------------------------------------------------------]]
-local Type, Version = "Keybinding", 27
+local Type, Version = "Keybinding", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -13,6 +13,10 @@ local pairs = pairs
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NOT_BOUND
+
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
@@ -30,15 +34,11 @@ local function Keybinding_OnClick(frame, button)
local self = frame.obj
if self.waitingForKey then
frame:EnableKeyboard(false)
- frame:EnableMouseWheel(false)
- frame:EnableGamePadButton(false)
self.msgframe:Hide()
frame:UnlockHighlight()
self.waitingForKey = nil
else
frame:EnableKeyboard(true)
- frame:EnableMouseWheel(true)
- frame:EnableGamePadButton(true)
self.msgframe:Show()
frame:LockHighlight()
self.waitingForKey = true
@@ -73,8 +73,6 @@ local function Keybinding_OnKeyDown(frame, key)
end
frame:EnableKeyboard(false)
- frame:EnableMouseWheel(false)
- frame:EnableGamePadButton(false)
self.msgframe:Hide()
frame:UnlockHighlight()
self.waitingForKey = nil
@@ -99,16 +97,6 @@ local function Keybinding_OnMouseDown(frame, button)
Keybinding_OnKeyDown(frame, button)
end
-local function Keybinding_OnMouseWheel(frame, direction)
- local button
- if direction >= 0 then
- button = "MOUSEWHEELUP"
- else
- button = "MOUSEWHEELDOWN"
- end
- Keybinding_OnKeyDown(frame, button)
-end
-
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
@@ -120,9 +108,6 @@ local methods = {
self.waitingForKey = nil
self.msgframe:Hide()
self:SetDisabled(false)
- self.button:EnableKeyboard(false)
- self.button:EnableMouseWheel(false)
- self.button:EnableGamePadButton(false)
end,
-- ["OnRelease"] = nil,
@@ -188,23 +173,18 @@ local function Constructor()
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
- local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
+ local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate2")
button:EnableMouse(true)
- button:EnableMouseWheel(false)
button:RegisterForClicks("AnyDown")
button:SetScript("OnEnter", Control_OnEnter)
button:SetScript("OnLeave", Control_OnLeave)
button:SetScript("OnClick", Keybinding_OnClick)
button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
- button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
- pcall(button.SetScript, button, "OnGamePadButtonDown", Keybinding_OnKeyDown)
button:SetPoint("BOTTOMLEFT")
button:SetPoint("BOTTOMRIGHT")
button:SetHeight(24)
- button:EnableKeyboard(false)
- button:EnableGamePadButton(false)
local text = button:GetFontString()
text:SetPoint("LEFT", 7, 0)
@@ -216,13 +196,12 @@ local function Constructor()
label:SetJustifyH("CENTER")
label:SetHeight(18)
- local msgframe = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
+ local msgframe = CreateFrame("Frame", nil, UIParent)
msgframe:SetHeight(30)
msgframe:SetBackdrop(ControlBackdrop)
msgframe:SetBackdropColor(0,0,0)
msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
msgframe:SetFrameLevel(1000)
- msgframe:SetToplevel(true)
local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
index d0841ef..7f5f1c5 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
@@ -2,7 +2,7 @@
Label Widget
Displays text and optionally an icon.
-------------------------------------------------------------------------------]]
-local Type, Version = "Label", 28
+local Type, Version = "Label", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -12,6 +12,10 @@ local max, select, pairs = math.max, select, pairs
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
@@ -35,30 +39,21 @@ local function UpdateImageAnchor(self)
label:SetPoint("TOP", image, "BOTTOM")
label:SetPoint("LEFT")
label:SetWidth(width)
- height = image:GetHeight() + label:GetStringHeight()
+ height = image:GetHeight() + label:GetHeight()
else
-- image on the left
image:SetPoint("TOPLEFT")
- if image:GetHeight() > label:GetStringHeight() then
- label:SetPoint("LEFT", image, "RIGHT", 4, 0)
- else
- label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
- end
+ label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
label:SetWidth(width - imagewidth - 4)
- height = max(image:GetHeight(), label:GetStringHeight())
+ height = max(image:GetHeight(), label:GetHeight())
end
else
-- no image shown
label:SetPoint("TOPLEFT")
label:SetWidth(width)
- height = label:GetStringHeight()
+ height = label:GetHeight()
end
-
- -- avoid zero-height labels, since they can used as spacers
- if not height or height == 0 then
- height = 1
- end
-
+
self.resizing = true
frame:SetHeight(height)
frame.height = height
@@ -79,8 +74,6 @@ local methods = {
self:SetImageSize(16, 16)
self:SetColor()
self:SetFontObject()
- self:SetJustifyH("LEFT")
- self:SetJustifyV("TOP")
-- reset the flag
self.resizing = nil
@@ -109,7 +102,7 @@ local methods = {
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
-
+
if image:GetTexture() then
self.imageshown = true
local n = select("#", ...)
@@ -125,16 +118,11 @@ local methods = {
end,
["SetFont"] = function(self, font, height, flags)
- if not self.fontObject then
- self.fontObject = CreateFont("AceGUI30LabelFont" .. AceGUI:GetNextWidgetNum(Type))
- end
- self.fontObject:SetFont(font, height, flags)
- self:SetFontObject(self.fontObject)
+ self.label:SetFont(font, height, flags)
end,
["SetFontObject"] = function(self, font)
- self.label:SetFontObject(font or GameFontHighlightSmall)
- UpdateImageAnchor(self)
+ self:SetFont((font or GameFontHighlightSmall):GetFont())
end,
["SetImageSize"] = function(self, width, height)
@@ -142,14 +130,6 @@ local methods = {
self.image:SetHeight(height)
UpdateImageAnchor(self)
end,
-
- ["SetJustifyH"] = function(self, justifyH)
- self.label:SetJustifyH(justifyH)
- end,
-
- ["SetJustifyV"] = function(self, justifyV)
- self.label:SetJustifyV(justifyV)
- end,
}
--[[-----------------------------------------------------------------------------
@@ -160,6 +140,9 @@ local function Constructor()
frame:Hide()
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
+ label:SetJustifyH("LEFT")
+ label:SetJustifyV("TOP")
+
local image = frame:CreateTexture(nil, "BACKGROUND")
-- create widget
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
index 3dcbaca..64d8dd7 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
@@ -1,4 +1,4 @@
-local Type, Version = "MultiLineEditBox", 33
+local Type, Version = "MultiLineEditBox", 23
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -6,34 +6,17 @@ if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local pairs = pairs
-- WoW APIs
-local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
+local GetCursorInfo, GetSpellName, ClearCursor = GetCursorInfo, GetSpellName, ClearCursor
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: ACCEPT, ChatFontNormal
+
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
-
-if not AceGUIMultiLineEditBoxInsertLink then
- -- upgradeable hook
- if ChatFrameUtil and ChatFrameUtil.InsertLink then
- hooksecurefunc(ChatFrameUtil, "InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
- elseif ChatEdit_InsertLink then
- hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
- end
-end
-
-function _G.AceGUIMultiLineEditBoxInsertLink(text)
- for i = 1, AceGUI:GetWidgetCount(Type) do
- local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
- if editbox and editbox:IsVisible() and editbox:HasFocus() then
- editbox:Insert(text)
- return true
- end
- end
-end
-
-
local function Layout(self)
self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
@@ -78,7 +61,6 @@ end
local function OnEditFocusLost(self) -- EditBox
self:HighlightText(0, 0)
- self.obj:Fire("OnEditFocusLost")
end
local function OnEnter(self) -- EditBox / ScrollFrame
@@ -104,12 +86,11 @@ local function OnMouseUp(self)
end
local function OnReceiveDrag(self) -- EditBox / ScrollFrame
- local type, id, info, extra = GetCursorInfo()
+ local type, id, info = GetCursorInfo()
if type == "spell" then
- if C_Spell and C_Spell.GetSpellName then
- info = C_Spell.GetSpellName(extra)
- else
- info = GetSpellInfo(id, info)
+ info, id = GetSpellName(id, info)
+ if id and id:match("%d") then
+ info = info .. "(" .. id .. ")"
end
elseif type ~= "item" then
return
@@ -149,24 +130,6 @@ local function OnVerticalScroll(self, offset)
editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
end
-local function OnScrollRangeChanged(self, xrange, yrange)
- if yrange == 0 then
- self.obj.editBox:SetHitRectInsets(0, 0, 0, 0)
- else
- OnVerticalScroll(self, self:GetVerticalScroll())
- end
-end
-
-local function OnShowFocus(frame)
- frame.obj.editBox:SetFocus()
- frame:SetScript("OnShow", nil)
-end
-
-local function OnEditFocusGained(frame)
- AceGUI:SetFocus(frame.obj)
- frame.obj:Fire("OnEditFocusGained")
-end
-
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
@@ -181,9 +144,7 @@ local methods = {
self:SetMaxLetters(0)
end,
- ["OnRelease"] = function(self)
- self:ClearFocus()
- end,
+ -- ["OnRelease"] = nil,
["SetDisabled"] = function(self, disabled)
local editBox = self.editBox
@@ -244,31 +205,7 @@ local methods = {
self.button:Show()
end
Layout(self)
- end,
-
- ["ClearFocus"] = function(self)
- self.editBox:ClearFocus()
- self.frame:SetScript("OnShow", nil)
- end,
-
- ["SetFocus"] = function(self)
- self.editBox:SetFocus()
- if not self.frame:IsShown() then
- self.frame:SetScript("OnShow", OnShowFocus)
- end
- end,
-
- ["HighlightText"] = function(self, from, to)
- self.editBox:HighlightText(from, to)
- end,
-
- ["GetCursorPosition"] = function(self)
- return self.editBox:GetCursorPosition()
- end,
-
- ["SetCursorPosition"] = function(self, ...)
- return self.editBox:SetCursorPosition(...)
- end,
+ end
}
--[[-----------------------------------------------------------------------------
@@ -283,7 +220,7 @@ local backdrop = {
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
-
+
local widgetNum = AceGUI:GetNextWidgetNum(Type)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
@@ -293,21 +230,21 @@ local function Constructor()
label:SetText(ACCEPT)
label:SetHeight(10)
- local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate")
+ local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate2")
button:SetPoint("BOTTOMLEFT", 0, 4)
button:SetHeight(22)
button:SetWidth(label:GetStringWidth() + 24)
button:SetText(ACCEPT)
button:SetScript("OnClick", OnClick)
button:Disable()
-
+
local text = button:GetFontString()
text:ClearAllPoints()
text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
text:SetJustifyV("MIDDLE")
- local scrollBG = CreateFrame("Frame", nil, frame, "BackdropTemplate")
+ local scrollBG = CreateFrame("Frame", nil, frame)
scrollBG:SetBackdrop(backdrop)
scrollBG:SetBackdropColor(0, 0, 0)
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
@@ -331,9 +268,8 @@ local function Constructor()
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
- scrollFrame:HookScript("OnScrollRangeChanged", OnScrollRangeChanged)
- local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
+ local editBox = CreateFrame("EditBox", nil, scrollFrame)
editBox:SetAllPoints()
editBox:SetFontObject(ChatFontNormal)
editBox:SetMultiLine(true)
@@ -349,8 +285,6 @@ local function Constructor()
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
editBox:SetScript("OnTextChanged", OnTextChanged)
editBox:SetScript("OnTextSet", OnTextSet)
- editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
-
scrollFrame:SetScrollChild(editBox)
diff --git a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
index 85b2ddb..7f0bd5f 100644
--- a/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
+++ b/Decursive/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
@@ -2,7 +2,7 @@
Slider Widget
Graphical Slider, like, for Range values.
-------------------------------------------------------------------------------]]
-local Type, Version = "Slider", 24
+local Type, Version = "Slider", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
@@ -14,6 +14,10 @@ local tonumber, pairs = tonumber, pairs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
@@ -27,13 +31,13 @@ local function UpdateText(self)
end
local function UpdateLabels(self)
- local min_value, max_value = (self.min or 0), (self.max or 100)
+ local min, max = (self.min or 0), (self.max or 100)
if self.ispercent then
- self.lowtext:SetFormattedText("%s%%", (min_value * 100))
- self.hightext:SetFormattedText("%s%%", (max_value * 100))
+ self.lowtext:SetFormattedText("%s%%", (min * 100))
+ self.hightext:SetFormattedText("%s%%", (max * 100))
else
- self.lowtext:SetText(min_value)
- self.hightext:SetText(max_value)
+ self.lowtext:SetText(min)
+ self.hightext:SetText(max)
end
end
@@ -53,13 +57,10 @@ local function Frame_OnMouseDown(frame)
AceGUI:ClearFocus()
end
-local function Slider_OnValueChanged(frame, newvalue)
+local function Slider_OnValueChanged(frame)
local self = frame.obj
if not frame.setup then
- if self.step and self.step > 0 then
- local min_value = self.min or 0
- newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
- end
+ local newvalue = frame:GetValue()
if newvalue ~= self.value and not self.disabled then
self.value = newvalue
self:Fire("OnValueChanged", newvalue)
@@ -101,9 +102,9 @@ local function EditBox_OnEnterPressed(frame)
else
value = tonumber(value)
end
-
+
if value then
- PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ PlaySound("igMainMenuOptionCheckBoxOn")
self.slider:SetValue(value)
self:Fire("OnMouseUp", value)
end
@@ -171,13 +172,13 @@ local methods = {
self.label:SetText(text)
end,
- ["SetSliderValues"] = function(self, min_value, max_value, step)
+ ["SetSliderValues"] = function(self, min, max, step)
local frame = self.slider
frame.setup = true
- self.min = min_value
- self.max = max_value
+ self.min = min
+ self.max = max
self.step = step
- frame:SetMinMaxValues(min_value or 0,max_value or 100)
+ frame:SetMinMaxValues(min or 0,max or 100)
UpdateLabels(self)
frame:SetValueStep(step or 1)
if self.value then
@@ -221,7 +222,7 @@ local function Constructor()
label:SetJustifyH("CENTER")
label:SetHeight(15)
- local slider = CreateFrame("Slider", nil, frame, "BackdropTemplate")
+ local slider = CreateFrame("Slider", nil, frame)
slider:SetOrientation("HORIZONTAL")
slider:SetHeight(15)
slider:SetHitRectInsets(0, 0, -10, 0)
@@ -243,7 +244,7 @@ local function Constructor()
local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
- local editbox = CreateFrame("EditBox", nil, frame, "BackdropTemplate")
+ local editbox = CreateFrame("EditBox", nil, frame)
editbox:SetAutoFocus(false)
editbox:SetFontObject(GameFontHighlightSmall)
editbox:SetPoint("TOP", slider, "BOTTOM")
@@ -273,7 +274,6 @@ local function Constructor()
widget[method] = func
end
slider.obj, editbox.obj = widget, widget
- C_Timer.After(0.3, function() editbox:SetText(" ") UpdateText(widget) end) -- Workaround for font loading issue, making the editboxes blank until the text is changed
return AceGUI:RegisterAsWidget(widget)
end
diff --git a/Decursive/Libs/AceHook-3.0/AceHook-3.0.lua b/Decursive/Libs/AceHook-3.0/AceHook-3.0.lua
index 3410f2c..096eb6f 100644
--- a/Decursive/Libs/AceHook-3.0/AceHook-3.0.lua
+++ b/Decursive/Libs/AceHook-3.0/AceHook-3.0.lua
@@ -2,15 +2,15 @@
-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
-- when you manually restore the original function.
--
--- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
+-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceHook itself.\\
-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceHook.
-- @class file
-- @name AceHook-3.0
--- @release $Id$
-local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 9
+-- @release $Id: AceHook-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
+local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
if not AceHook then return end -- No upgrade needed
@@ -117,14 +117,14 @@ function donothing() end
function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
if not handler then handler = method end
-
+
-- These asserts make sure AceHooks's devs play by the rules.
assert(not script or type(script) == "boolean")
assert(not secure or type(secure) == "boolean")
assert(not raw or type(raw) == "boolean")
assert(not forceSecure or type(forceSecure) == "boolean")
assert(usage)
-
+
-- Error checking Battery!
if obj and type(obj) ~= "table" then
error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
@@ -139,15 +139,15 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
end
if script then
+ if not secure and obj:IsProtected() and protectedScripts[method] then
+ error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
+ end
if not obj or not obj.GetScript or not obj:HasScript(method) then
error(format("%s: You can only hook a script on a frame object", usage), 3)
end
- if not secure and obj.IsProtected and obj:IsProtected() and protectedScripts[method] then
- error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
- end
else
- local issecure
- if obj then
+ local issecure
+ if obj then
issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
else
issecure = onceSecure[method] or issecurevariable(method)
@@ -165,21 +165,21 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
end
end
end
-
+
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
-
+
if uid then
if actives[uid] then
-- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
error(format("Attempting to rehook already active hook %s.", method))
end
-
+
if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
actives[uid] = true
return
@@ -195,8 +195,9 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
registry[self][method] = nil
end
handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
+ uid = nil
end
-
+
local orig
if script then
orig = obj:GetScript(method) or donothing
@@ -205,13 +206,13 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
else
orig = _G[method]
end
-
+
if not orig then
error(format("%s: Attempting to hook a non existing target", usage), 3)
end
-
+
uid = createHook(self, handler, orig, secure, not (raw or secure))
-
+
if obj then
self.hooks[obj] = self.hooks[obj] or {}
registry[self][obj] = registry[self][obj] or {}
@@ -220,11 +221,14 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
if not secure then
self.hooks[obj][method] = orig
end
-
+
if script then
- if not secure then
+ -- If the script is empty before, HookScript will not work, so use SetScript instead
+ -- This will make the hook insecure, but shouldnt matter, since it was empty before.
+ -- It does not taint the full frame.
+ if not secure or orig == donothing then
obj:SetScript(method, uid)
- else
+ elseif secure then
obj:HookScript(method, uid)
end
else
@@ -236,7 +240,7 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
end
else
registry[self][method] = uid
-
+
if not secure then
_G[method] = uid
self.hooks[method] = orig
@@ -244,8 +248,8 @@ function hook(self, obj, method, handler, script, secure, raw, forceSecure, usag
hooksecurefunc(method, uid)
end
end
-
- actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
+
+ actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
end
--- Hook a function or a method on an object.
@@ -261,7 +265,7 @@ end
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
+--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:Hook("ActionButton_UpdateHotkeys", true)
@@ -274,12 +278,12 @@ function AceHook:Hook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
-
+
if handler == true then
handler, hookSecure = nil, true
end
- hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
+ hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
end
--- RawHook a function or a method on an object.
@@ -296,7 +300,7 @@ end
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
+--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:RawHook("ActionButton_UpdateHotkeys", true)
@@ -313,11 +317,11 @@ function AceHook:RawHook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
-
+
if handler == true then
handler, hookSecure = nil, true
end
-
+
hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
end
@@ -336,7 +340,7 @@ function AceHook:SecureHook(object, method, handler)
if type(object) == "string" then
method, handler, object = object, method, nil
end
-
+
hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
end
@@ -353,9 +357,9 @@ end
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
+--
-- function MyAddon:OnEnable()
--- -- Hook the OnShow of FriendsFrame
+-- -- Hook the OnShow of FriendsFrame
-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
@@ -379,9 +383,9 @@ end
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
+--
-- function MyAddon:OnEnable()
--- -- Hook the OnShow of FriendsFrame
+-- -- Hook the OnShow of FriendsFrame
-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
@@ -419,54 +423,54 @@ function AceHook:Unhook(obj, method)
if type(obj) == "string" then
method, obj = obj, nil
end
-
+
if obj and type(obj) ~= "table" then
error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
end
if type(method) ~= "string" then
error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
end
-
+
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
-
+
if not uid or not actives[uid] then
-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
return false
end
-
+
actives[uid], handlers[uid] = nil, nil
-
+
if obj then
registry[self][obj][method] = nil
registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
-
+
-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
if not self.hooks[obj] or not self.hooks[obj][method] then return true end
-
+
if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
- obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
+ obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
scripts[uid] = nil
elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
obj[method] = self.hooks[obj][method]
end
-
+
self.hooks[obj][method] = nil
self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
else
registry[self][method] = nil
-
+
-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
if not self.hooks[method] then return true end
-
+
if self.hooks[method] and _G[method] == uid then -- unhooks functions
_G[method] = self.hooks[method]
end
-
+
self.hooks[method] = nil
end
return true
@@ -477,10 +481,10 @@ function AceHook:UnhookAll()
for key, value in pairs(registry[self]) do
if type(key) == "table" then
for method in pairs(value) do
- AceHook.Unhook(self, key, method)
+ self:Unhook(key, method)
end
else
- AceHook.Unhook(self, key)
+ self:Unhook(key)
end
end
end
@@ -500,7 +504,7 @@ function AceHook:IsHooked(obj, method)
return true, handlers[registry[self][obj][method]]
end
end
-
+
return false, nil
end
diff --git a/Decursive/Libs/AceLocale-3.0/AceLocale-3.0.lua b/Decursive/Libs/AceLocale-3.0/AceLocale-3.0.lua
index bb0438d..0f7c8fd 100644
--- a/Decursive/Libs/AceLocale-3.0/AceLocale-3.0.lua
+++ b/Decursive/Libs/AceLocale-3.0/AceLocale-3.0.lua
@@ -1,8 +1,8 @@
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
--- @release $Id$
-local MAJOR,MINOR = "AceLocale-3.0", 6
+-- @release $Id: AceLocale-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
+local MAJOR,MINOR = "AceLocale-3.0", 2
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
@@ -10,7 +10,11 @@ if not AceLocale then return end -- no upgrade needed
-- Lua APIs
local assert, tostring, error = assert, tostring, error
-local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GAME_LOCALE, geterrorhandler
local gameLocale = GetLocale()
if gameLocale == "enGB" then
@@ -52,10 +56,10 @@ local writeproxy = setmetatable({}, {
__index = assertfalse
})
--- This metatable proxy is used when registering the default locale.
+-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
--- Reason 2: If 2 modules have the same string, but only the first one to be
+-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
@@ -75,7 +79,7 @@ local writedefaultproxy = setmetatable({}, {
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
--- @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).
+-- @param silent If true, the locale will not issue warnings for missing keys. Can only be set on the default locale.
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
@@ -87,32 +91,31 @@ local writedefaultproxy = setmetatable({}, {
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
-
- -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
- local activeGameLocale = GAME_LOCALE or gameLocale
-
- local app = AceLocale.apps[application]
-
- if silent and app and getmetatable(app) ~= readmetasilent then
- geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
+
+ if silent and not isDefault then
+ error("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' can only be specified for the default locale", 2)
end
+
+ -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
+ -- Ammo: I still think this is a bad idea, for instance an addon that checks for some ingame string will fail, just because some other addon
+ -- gives the user the illusion that they can run in a different locale? Ditch this whole thing or allow a setting per 'application'. I'm of the
+ -- opinion to remove this.
+ local gameLocale = GAME_LOCALE or gameLocale
+ if locale ~= gameLocale and not isDefault then
+ return -- nop, we don't need these translations
+ end
+
+ local app = AceLocale.apps[application]
+
if not app then
- if silent=="raw" then
- app = {}
- else
- app = setmetatable({}, silent and readmetasilent or readmeta)
- end
+ app = setmetatable({}, silent and readmetasilent or readmeta)
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
- if locale ~= activeGameLocale and not isDefault then
- return -- nop, we don't need these translations
- end
-
registering = app -- remember globally for writeproxy and writedefaultproxy
-
+
if isDefault then
return writedefaultproxy
end
diff --git a/Decursive/Libs/AceTimer-3.0/AceTimer-3.0.lua b/Decursive/Libs/AceTimer-3.0/AceTimer-3.0.lua
index e84d420..fdb2cff 100644
--- a/Decursive/Libs/AceTimer-3.0/AceTimer-3.0.lua
+++ b/Decursive/Libs/AceTimer-3.0/AceTimer-3.0.lua
@@ -1,124 +1,296 @@
--- **AceTimer-3.0** provides a central facility for registering timers.
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
--- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
+-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
--- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API
--- restricts us to.
+-- AceTimer is currently limited to firing timers at a frequency of 0.1s. This constant may change
+-- in the future, but for now it seemed like a good compromise in efficiency and accuracy.
--
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
--- need to cancel the timer you just registered.
+-- need to cancel or reschedule the timer you just registered.
--
--- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
+-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceTimer.
-- @class file
-- @name AceTimer-3.0
--- @release $Id$
+-- @release $Id: AceTimer-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
-local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes
+--[[
+ Basic assumptions:
+ * In a typical system, we do more re-scheduling per second than there are timer pulses per second
+ * Regardless of timer implementation, we cannot guarantee timely delivery due to FPS restriction (may be as low as 10)
+
+ This implementation:
+ CON: The smallest timer interval is constrained by HZ (currently 1/10s).
+ PRO: It will still correctly fire any timer slower than HZ over a length of time, e.g. 0.11s interval -> 90 times over 10 seconds
+ PRO: In lag bursts, the system simly skips missed timer intervals to decrease load
+ CON: Algorithms depending on a timer firing "N times per minute" will fail
+ PRO: (Re-)scheduling is O(1) with a VERY small constant. It's a simple linked list insertion in a hash bucket.
+ CAUTION: The BUCKETS constant constrains how many timers can be efficiently handled. With too many hash collisions, performance will decrease.
+
+ Major assumptions upheld:
+ - ALLOWS scheduling multiple timers with the same funcref/method
+ - ALLOWS scheduling more timers during OnUpdate processing
+ - ALLOWS unscheduling ANY timer (including the current running one) at any time, including during OnUpdate processing
+]]
+
+local MAJOR, MINOR = "AceTimer-3.0", 5
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceTimer then return end -- No upgrade needed
-AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
-local activeTimers = AceTimer.activeTimers -- Upvalue our private data
+
+AceTimer.hash = AceTimer.hash or {} -- Array of [0..BUCKET-1] = linked list of timers (using .next member)
+ -- Linked list gets around ACE-88 and ACE-90.
+AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
+AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
-- Lua APIs
-local type, unpack, next, error, select = type, unpack, next, error, select
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local select, pairs, type, next, tostring = select, pairs, type, next, tostring
+local floor, max, min = math.floor, math.max, math.min
+local tconcat = table.concat
+
-- WoW APIs
-local GetTime, C_TimerAfter = GetTime, C_Timer.After
+local GetTime = GetTime
-local function new(self, loop, func, delay, ...)
- if delay < 0.01 then
- delay = 0.01 -- Restrict to the lowest time that the C_Timer API allows us
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: DEFAULT_CHAT_FRAME, geterrorhandler
+
+-- Simple ONE-SHOT timer cache. Much more efficient than a full compost for our purposes.
+local timerCache = nil
+
+--[[
+ Timers will not be fired more often than HZ-1 times per second.
+ Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
+ If this is ever LOWERED, all existing timers need to be enforced to have a delay >= 1/HZ on lib upgrade.
+ If this number is ever changed, all entries need to be rehashed on lib upgrade.
+ ]]
+local HZ = 11
+
+--[[
+ Prime for good distribution
+ If this number is ever changed, all entries need to be rehashed on lib upgrade.
+]]
+local BUCKETS = 131
+
+local hash = AceTimer.hash
+for i=1,BUCKETS do
+ hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
+end
+
+--[[
+ xpcall safecall implementation
+]]
+local xpcall = xpcall
+
+local function errorhandler(err)
+ return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+ local code = [[
+ local xpcall, eh = ... -- our arguments are received as unnamed values in "..." since we don't have a proper function declaration
+ local method, ARGS
+ local function call() return method(ARGS) end
+
+ local function dispatch(func, ...)
+ method = func
+ if not method then return end
+ ARGS = ...
+ return xpcall(call, eh)
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS = {}
+ for i = 1, argCount do ARGS[i] = "arg"..i end
+ code = code:gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {
+ __index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
end
+})
+Dispatchers[0] = function(func)
+ return xpcall(func, errorhandler)
+end
+
+local function safecall(func, ...)
+ return Dispatchers[select('#', ...)](func, ...)
+end
- local timer = {
- object = self,
- func = func,
- looping = loop,
- argsCount = select("#", ...),
- delay = delay,
- ends = GetTime() + delay,
- ...
- }
+local lastint = floor(GetTime() * HZ)
- activeTimers[timer] = timer
+-- --------------------------------------------------------------------
+-- OnUpdate handler
+--
+-- traverse buckets, always chasing "now", and fire timers that have expired
- -- Create new timer closure to wrap the "timer" object
- timer.callback = function()
- if not timer.cancelled then
- if type(timer.func) == "string" then
- -- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
- -- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
- timer.object[timer.func](timer.object, unpack(timer, 1, timer.argsCount))
- else
- timer.func(unpack(timer, 1, timer.argsCount))
- end
+local function OnUpdate()
+ local now = GetTime()
+ local nowint = floor(now * HZ)
+
+ -- Have we passed into a new hash bucket?
+ if nowint == lastint then return end
+
+ local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2
+
+ -- Pass through each bucket at most once
+ -- Happens on e.g. instance loads, but COULD happen on high local load situations also
+ for curint = (max(lastint, nowint - BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteration
+ local curbucket = (curint % BUCKETS)+1
+ -- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks.
+ local nexttimer = hash[curbucket]
+ hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash
- if timer.looping and not timer.cancelled then
- -- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
- -- due to fps differences
- local time = GetTime()
- local ndelay = timer.delay - (time - timer.ends)
- -- Ensure the delay doesn't go below the threshold
- if ndelay < 0.01 then ndelay = 0.01 end
- C_TimerAfter(ndelay, timer.callback)
- timer.ends = time + ndelay
- else
- activeTimers[timer.handle or timer] = nil
- end
+ while nexttimer do
+ local timer = nexttimer
+ nexttimer = timer.next
+ local when = timer.when
+
+ if when < soon then
+ -- Call the timer func, either as a method on given object, or a straight function ref
+ local callback = timer.callback
+ if type(callback) == "string" then
+ safecall(timer.object[callback], timer.object, timer.arg)
+ elseif callback then
+ safecall(callback, timer.arg)
+ else
+ -- probably nilled out by CancelTimer
+ timer.delay = nil -- don't reschedule it
+ end
+
+ local delay = timer.delay -- NOW make a local copy, can't do it earlier in case the timer cancelled itself in the callback
+
+ if not delay then
+ -- single-shot timer (or cancelled)
+ AceTimer.selfs[timer.object][tostring(timer)] = nil
+ timerCache = timer
+ else
+ -- repeating timer
+ local newtime = when + delay
+ if newtime < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
+ newtime = now + delay
+ end
+ timer.when = newtime
+
+ -- add next timer execution to the correct bucket
+ local bucket = (floor(newtime * HZ) % BUCKETS) + 1
+ timer.next = hash[bucket]
+ hash[bucket] = timer
+ end
+ else -- if when>=soon
+ -- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution)
+ timer.next = hash[curbucket]
+ hash[curbucket] = timer
+ end -- if whenhandle->timer registry
+ local handle = tostring(timer)
+
+ local selftimers = AceTimer.selfs[self]
+ if not selftimers then
+ selftimers = {}
+ AceTimer.selfs[self] = selftimers
+ end
+ selftimers[handle] = timer
+ selftimers.__ops = (selftimers.__ops or 0) + 1
+
+ return handle
end
--- Schedule a new one-shot timer.
-- The timer will fire once in `delay` seconds, unless canceled before.
--- @param func Callback function for the timer pulse (funcref or method name).
+-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
--- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @param arg An optional argument to be passed to the callback function.
-- @usage
--- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
---
--- function MyAddOn:OnEnable()
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
+--
+-- function MyAddon:OnEnable()
-- self:ScheduleTimer("TimerFeedback", 5)
-- end
--
--- function MyAddOn:TimerFeedback()
+-- function MyAddon:TimerFeedback()
-- print("5 seconds passed")
-- end
-function AceTimer:ScheduleTimer(func, delay, ...)
- if not func or not delay then
- error(MAJOR..": ScheduleTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
- end
- if type(func) == "string" then
- if type(self) ~= "table" then
- error(MAJOR..": ScheduleTimer(callback, delay, args...): 'self' - must be a table.", 2)
- elseif not self[func] then
- error(MAJOR..": ScheduleTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
- end
- end
- return new(self, nil, func, delay, ...)
+function AceTimer:ScheduleTimer(callback, delay, arg)
+ return Reg(self, callback, delay, arg)
end
--- Schedule a repeating timer.
-- The timer will fire every `delay` seconds, until canceled.
--- @param func Callback function for the timer pulse (funcref or method name).
+-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
--- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @param arg An optional argument to be passed to the callback function.
-- @usage
--- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
---
--- function MyAddOn:OnEnable()
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
+--
+-- function MyAddon:OnEnable()
-- self.timerCount = 0
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
-- end
--
--- function MyAddOn:TimerFeedback()
+-- function MyAddon:TimerFeedback()
-- self.timerCount = self.timerCount + 1
-- print(("%d seconds passed"):format(5 * self.timerCount))
-- -- run 30 seconds in total
@@ -126,124 +298,129 @@ end
-- self:CancelTimer(self.testTimer)
-- end
-- end
-function AceTimer:ScheduleRepeatingTimer(func, delay, ...)
- if not func or not delay then
- error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
- end
- if type(func) == "string" then
- if type(self) ~= "table" then
- error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'self' - must be a table.", 2)
- elseif not self[func] then
- error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
- end
- end
- return new(self, true, func, delay, ...)
+function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
+ return Reg(self, callback, delay, arg, true)
end
---- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
--- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
+--- Cancels a timer with the given handle, registered by the same addon object as used for `:ScheduleTimer`
+-- Both one-shot and repeating timers can be canceled with this function, as long as the `handle` is valid
-- and the timer has not fired yet or was canceled before.
--- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-function AceTimer:CancelTimer(id)
- local timer = activeTimers[id]
-
- if not timer then
- return false
+-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+-- @param silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
+-- @return True if the timer was successfully cancelled.
+function AceTimer:CancelTimer(handle, silent)
+ if not handle then return end -- nil handle -> bail out without erroring
+ if type(handle) ~= "string" then
+ error(MAJOR..": CancelTimer(handle): 'handle' - expected a string", 2) -- for now, anyway
+ end
+ local selftimers = AceTimer.selfs[self]
+ local timer = selftimers and selftimers[handle]
+ if silent then
+ if timer then
+ timer.callback = nil -- don't run it again
+ timer.delay = nil -- if this is the currently-executing one: don't even reschedule
+ -- The timer object is removed in the OnUpdate loop
+ end
+ return not not timer -- might return "true" even if we double-cancel. we'll live.
else
- timer.cancelled = true
- activeTimers[id] = nil
+ if not timer then
+ geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
+ return false
+ end
+ if not timer.callback then
+ geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
+ return false
+ end
+ timer.callback = nil -- don't run it again
+ timer.delay = nil -- if this is the currently-executing one: don't even reschedule
return true
end
end
--- Cancels all timers registered to the current addon object ('self')
function AceTimer:CancelAllTimers()
- for k,v in next, activeTimers do
- if v.object == self then
- AceTimer.CancelTimer(self, k)
+ if not(type(self) == "string" or type(self) == "table") then
+ error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
+ end
+ if self == AceTimer then
+ error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
+ end
+
+ local selftimers = AceTimer.selfs[self]
+ if selftimers then
+ for handle,v in pairs(selftimers) do
+ if type(v) == "table" then -- avoid __ops, etc
+ AceTimer.CancelTimer(self, handle, true)
+ end
end
end
end
---- Returns the time left for a timer with the given id, registered by the current addon object ('self').
--- This function will return 0 when the id is invalid.
--- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
--- @return The time left on the timer.
-function AceTimer:TimeLeft(id)
- local timer = activeTimers[id]
- if not timer then
- return 0
- else
- return timer.ends - GetTime()
+--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
+-- This function will raise a warning when the handle is invalid, but not stop execution.
+-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+-- @return The time left on the timer, or false if the handle is invalid.
+function AceTimer:TimeLeft(handle)
+ if not handle then return end
+ if type(handle) ~= "string" then
+ error(MAJOR..": TimeLeft(handle): 'handle' - expected a string", 2) -- for now, anyway
end
+ local selftimers = AceTimer.selfs[self]
+ local timer = selftimers and selftimers[handle]
+ if not timer then
+ geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
+ return false
+ end
+ return timer.when - GetTime()
end
-- ---------------------------------------------------------------------
--- Upgrading
+-- PLAYER_REGEN_ENABLED: Run through our .selfs[] array step by step
+-- and clean it out - otherwise the table indices can grow indefinitely
+-- if an addon starts and stops a lot of timers. AceBucket does this!
+--
+-- See ACE-94 and tests/AceTimer-3.0-ACE-94.lua
--- Upgrade from old hash-bucket based timers to C_Timer.After timers.
-if oldminor and oldminor < 10 then
- -- disable old timer logic
- AceTimer.frame:SetScript("OnUpdate", nil)
- AceTimer.frame:SetScript("OnEvent", nil)
- AceTimer.frame:UnregisterAllEvents()
- -- convert timers
- for object,timers in next, AceTimer.selfs do
- for handle,timer in next, timers do
- if type(timer) == "table" and timer.callback then
- local newTimer
- if timer.delay then
- newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.callback, timer.delay, timer.arg)
- else
- newTimer = AceTimer.ScheduleTimer(timer.object, timer.callback, timer.when - GetTime(), timer.arg)
- end
- -- Use the old handle for old timers
- activeTimers[newTimer] = nil
- activeTimers[handle] = newTimer
- newTimer.handle = handle
- end
- end
- end
- AceTimer.selfs = nil
- AceTimer.hash = nil
- AceTimer.debug = nil
-elseif oldminor and oldminor < 17 then
- -- Upgrade from old animation based timers to C_Timer.After timers.
- AceTimer.inactiveTimers = nil
- AceTimer.frame = nil
- local oldTimers = AceTimer.activeTimers
- -- Clear old timer table and update upvalue
- AceTimer.activeTimers = {}
- activeTimers = AceTimer.activeTimers
- for handle, timer in next, oldTimers do
- local newTimer
- -- Stop the old timer animation
- local duration, elapsed = timer:GetDuration(), timer:GetElapsed()
- timer:GetParent():Stop()
- if timer.looping then
- newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.func, duration, unpack(timer.args, 1, timer.argsCount))
- else
- newTimer = AceTimer.ScheduleTimer(timer.object, timer.func, duration - elapsed, unpack(timer.args, 1, timer.argsCount))
- end
- -- Use the old handle for old timers
- activeTimers[newTimer] = nil
- activeTimers[handle] = newTimer
- newTimer.handle = handle
- end
+local lastCleaned = nil
- -- Migrate transitional handles
- if oldminor < 13 and AceTimer.hashCompatTable then
- for handle, id in next, AceTimer.hashCompatTable do
- local t = activeTimers[id]
- if t then
- activeTimers[id] = nil
- activeTimers[handle] = t
- t.handle = handle
- end
- end
- AceTimer.hashCompatTable = nil
+local function OnEvent(this, event)
+ if event~="PLAYER_REGEN_ENABLED" then
+ return
end
+
+ -- Get the next 'self' to process
+ local selfs = AceTimer.selfs
+ local self = next(selfs, lastCleaned)
+ if not self then
+ self = next(selfs)
+ end
+ lastCleaned = self
+ if not self then -- should only happen if .selfs[] is empty
+ return
+ end
+
+ -- Time to clean it out?
+ local list = selfs[self]
+ if (list.__ops or 0) < 250 then -- 250 slosh indices = ~10KB wasted (max!). For one 'self'.
+ return
+ end
+
+ -- Create a new table and copy all members over
+ local newlist = {}
+ local n=0
+ for k,v in pairs(list) do
+ newlist[k] = v
+ n=n+1
+ end
+ newlist.__ops = 0 -- Reset operation count
+
+ -- And since we now have a count of the number of live timers, check that it's reasonable. Emit a warning if not.
+ if n>BUCKETS then
+ DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
+ end
+
+ selfs[self] = newlist
end
-- ---------------------------------------------------------------------
@@ -252,27 +429,45 @@ end
AceTimer.embeds = AceTimer.embeds or {}
local mixins = {
- "ScheduleTimer", "ScheduleRepeatingTimer",
+ "ScheduleTimer", "ScheduleRepeatingTimer",
"CancelTimer", "CancelAllTimers",
"TimeLeft"
}
function AceTimer:Embed(target)
AceTimer.embeds[target] = true
- for _,v in next, mixins do
+ for _,v in pairs(mixins) do
target[v] = AceTimer[v]
end
return target
end
--- AceTimer:OnEmbedDisable(target)
+-- AceTimer:OnEmbedDisable( target )
-- target (object) - target object that AceTimer is embedded in.
--
-- cancel all timers registered for the object
-function AceTimer:OnEmbedDisable(target)
+function AceTimer:OnEmbedDisable( target )
target:CancelAllTimers()
end
-for addon in next, AceTimer.embeds do
+
+for addon in pairs(AceTimer.embeds) do
AceTimer:Embed(addon)
end
+
+-- ---------------------------------------------------------------------
+-- Debug tools (expose copies of internals to test suites)
+AceTimer.debug = AceTimer.debug or {}
+AceTimer.debug.HZ = HZ
+AceTimer.debug.BUCKETS = BUCKETS
+
+-- ---------------------------------------------------------------------
+-- Finishing touchups
+
+AceTimer.frame:SetScript("OnUpdate", OnUpdate)
+AceTimer.frame:SetScript("OnEvent", OnEvent)
+AceTimer.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
+
+-- In theory, we should hide&show the frame based on there being timers or not.
+-- However, this job is fairly expensive, and the chance that there will
+-- actually be zero timers running is diminuitive to say the lest.
diff --git a/Decursive/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/Decursive/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
index 05fb9d2..274016c 100644
--- a/Decursive/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
+++ b/Decursive/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -1,5 +1,5 @@
---[[ $Id: CallbackHandler-1.0.lua 25 2022-12-12 15:02:36Z nevcairiel $ ]]
-local MAJOR, MINOR = "CallbackHandler-1.0", 8
+--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 6
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed
@@ -7,20 +7,56 @@ if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- Lua APIs
-local securecallfunction, error = securecallfunction, error
-local setmetatable, rawget = setmetatable, rawget
+local tconcat = table.concat
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler
-local function Dispatch(handlers, ...)
- local index, method = next(handlers)
- if not method then return end
- repeat
- securecallfunction(method, ...)
- index, method = next(handlers, index)
- until not method
+local xpcall = xpcall
+
+local function errorhandler(err)
+ return geterrorhandler()(err)
end
+local function CreateDispatcher(argCount)
+ local code = [[
+ local next, xpcall, eh = ...
+
+ local method, ARGS
+ local function call() method(ARGS) end
+
+ local function dispatch(handlers, ...)
+ local index
+ index, method = next(handlers)
+ if not method then return end
+ local OLD_ARGS = ARGS
+ ARGS = ...
+ repeat
+ xpcall(call, eh)
+ index, method = next(handlers, index)
+ until not method
+ ARGS = OLD_ARGS
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS, OLD_ARGS = {}, {}
+ for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
+ code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
+end})
+
--------------------------------------------------------------------------
-- CallbackHandler:New
--
@@ -29,7 +65,9 @@ end
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
-function CallbackHandler.New(_self, target, RegisterName, UnregisterName, UnregisterAllName)
+function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
+ -- TODO: Remove this after beta has gone out
+ assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
@@ -51,19 +89,19 @@ function CallbackHandler.New(_self, target, RegisterName, UnregisterName, Unregi
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
- Dispatch(events[eventname], eventname, ...)
+ Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
registry.recurse = oldrecurse
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
- for event,callbacks in pairs(registry.insertQueue) do
- local first = not rawget(events, event) or not next(events[event]) -- test for empty before. not test for one member after. that one member may have been overwritten.
- for object,func in pairs(callbacks) do
- events[event][object] = func
+ for eventname,callbacks in pairs(registry.insertQueue) do
+ local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
+ for self,func in pairs(callbacks) do
+ events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
- registry.OnUsed(registry, target, event)
+ registry.OnUsed(registry, target, eventname)
first = nil
end
end
diff --git a/Decursive/Localization/deDE.lua b/Decursive/Localization/deDE.lua
index 198ff43..b3184a7 100644
--- a/Decursive/Localization/deDE.lua
+++ b/Decursive/Localization/deDE.lua
@@ -99,7 +99,6 @@ L["BINDING_NAME_DCRSKLIST"] = "Ignorierliste ausgeben"
L["BINDING_NAME_DCRSKSHOW"] = "Zeige/Verstecke die Ignorierliste UI"
L["BLACK_LENGTH"] = "Sekunden auf der Blacklist: "
L["BLACKLISTED"] = "Black-listed"
-L["BLEED"] = "Blutung"
L["CHARM"] = "Verführung/Übernommen/Gedankenkontrolle"
L["CLASS_HUNTER"] = "Jäger"
L["CLEAR_PRIO"] = "C"
@@ -197,7 +196,6 @@ L["OPT_ANCHOR_DESC"] = "Zeigt Anker des Rahmens der allgemeinen Mitteilungen an"
L["OPT_AUTOHIDEMFS"] = "Automatisch verstecken"
L["OPT_AUTOHIDEMFS_DESC"] = "Wähle, wann das MUF-Fenster verborgen werden soll."
L["OPT_BLACKLENTGH_DESC"] = "Definiert wie lange ein Spieler auf der Blacklist steht. "
-L["OPT_BLEEDCHECK_DESC"] = "Wenn markiert, kannst du Blutungseffekte sehen und entfernen (CoA: Zauber wie 'Ausbrennen', die die Blutungs-Mechanik aufheben)"
L["OPT_BORDERTRANSP"] = "Rahmen-Transparenz"
L["OPT_BORDERTRANSP_DESC"] = "Rahmen-Transparenz setzten"
L["OPT_CENTERTRANSP"] = "Transparenz Mitte"
diff --git a/Decursive/Localization/enUS.lua b/Decursive/Localization/enUS.lua
index 53ddee9..7990fc1 100644
--- a/Decursive/Localization/enUS.lua
+++ b/Decursive/Localization/enUS.lua
@@ -98,7 +98,6 @@ L["BINDING_NAME_DCRSKLIST"] = "Print the skip list"
L["BINDING_NAME_DCRSKSHOW"] = "Show or hide the skip list"
L["BLACK_LENGTH"] = "Seconds on the blacklist : "
L["BLACKLISTED"] = "Black-listed"
-L["BLEED"] = "Bleed"
L["CHARM"] = "Charm"
L["CLASS_HUNTER"] = "Hunter"
L["CLEAR_PRIO"] = "C"
@@ -198,7 +197,6 @@ L["OPT_ANCHOR_DESC"] = "Shows the anchor of the custom message frame"
L["OPT_AUTOHIDEMFS"] = "Auto-Hide"
L["OPT_AUTOHIDEMFS_DESC"] = "Choose when to hide the MUF window"
L["OPT_BLACKLENTGH_DESC"] = "Defines how long someone stays on the blacklist"
-L["OPT_BLEEDCHECK_DESC"] = "If checked you'll be able to see and remove bleed effects (CoA: spells like Cauterize that clear bleed mechanic)"
L["OPT_BORDERTRANSP"] = "Border transparency"
L["OPT_BORDERTRANSP_DESC"] = "Set the transparency of the border"
L["OPT_CENTERTRANSP"] = "Center transparency"
diff --git a/Decursive/Localization/esES.lua b/Decursive/Localization/esES.lua
index bf2e9e1..c6179aa 100644
--- a/Decursive/Localization/esES.lua
+++ b/Decursive/Localization/esES.lua
@@ -72,7 +72,6 @@ if not L then
return;
end;
-L["BLEED"] = "Sangrado"
L["CLASS_HUNTER"] = "Cazador"
L["CURSE"] = "Maldición"
L["DEFAULT_MACROKEY"] = "NONE"
diff --git a/Decursive/Localization/frFR.lua b/Decursive/Localization/frFR.lua
index cbc09f1..7d2d67d 100644
--- a/Decursive/Localization/frFR.lua
+++ b/Decursive/Localization/frFR.lua
@@ -99,7 +99,6 @@ L["BINDING_NAME_DCRSKLIST"] = "Afficher la liste des exceptions"
L["BINDING_NAME_DCRSKSHOW"] = "Afficher ou Cacher la liste des exceptions"
L["BLACK_LENGTH"] = "Délais (Secs) sur la *blacklist* : "
L["BLACKLISTED"] = "Sur liste noire"
-L["BLEED"] = "Saignement"
L["CHARM"] = "Possession"
L["CLASS_HUNTER"] = "Chasseur"
L["CLEAR_PRIO"] = "E"
@@ -198,7 +197,6 @@ L["OPT_ANCHOR_DESC"] = "Montre l'ancre de la fenêtre de discussion spéciale"
L["OPT_AUTOHIDEMFS"] = "Masquer automatiquement"
L["OPT_AUTOHIDEMFS_DESC"] = "Choisissez quand la fenêtre des micro-portraits doit être masquée automatiquement."
L["OPT_BLACKLENTGH_DESC"] = "Définit combien de temps quelqu'un reste sur liste noire"
-L["OPT_BLEEDCHECK_DESC"] = "Si cochée, vous pourrez voir et retirer les effets de saignement (CoA : sorts comme « Cautérisation » qui dissipent la mécanique de saignement)"
L["OPT_BORDERTRANSP"] = "Transparence de la bordure"
L["OPT_BORDERTRANSP_DESC"] = "Règle la transparence de la bordure"
L["OPT_CENTERTRANSP"] = "Transparence du centre"
diff --git a/Decursive/Localization/koKR.lua b/Decursive/Localization/koKR.lua
index 70a8032..28244c4 100644
--- a/Decursive/Localization/koKR.lua
+++ b/Decursive/Localization/koKR.lua
@@ -103,7 +103,6 @@ L["BINDING_NAME_DCRSKLIST"] = "제외 목록 출력"
L["BINDING_NAME_DCRSKSHOW"] = "제외 목록 표시/숨김"
L["BLACK_LENGTH"] = "블랙리스트 추가 시간(초) : "
L["BLACKLISTED"] = "블랙리스트됨"
-L["BLEED"] = "출혈"
L["CHARM"] = "변이"
L["CLASS_HUNTER"] = "사냥꾼"
L["CLEAR_PRIO"] = "C"
@@ -205,7 +204,6 @@ L["OPT_ANCHOR_DESC"] = "사용자 정의 메세지창의 고정위치를 표시
L["OPT_AUTOHIDEMFS"] = "자동숨김"
L["OPT_AUTOHIDEMFS_DESC"] = "선택하면 언제 MUF창을 숨겨둘지 설정합니다."
L["OPT_BLACKLENTGH_DESC"] = "블랙리스트에 등록할 시간을 지정합니다."
-L["OPT_BLEEDCHECK_DESC"] = "선택 시 출혈 효과를 표시하고 제거합니다 (CoA: '소작' 등 출혈 메커니즘을 해제하는 주문)"
L["OPT_BORDERTRANSP"] = "테두리 투명도"
L["OPT_BORDERTRANSP_DESC"] = "테두리의 투명도를 설정합니다."
L["OPT_CENTERTRANSP"] = "가운데 투명도"
diff --git a/Decursive/Localization/ruRU.lua b/Decursive/Localization/ruRU.lua
index ae23d07..4a11c6a 100644
--- a/Decursive/Localization/ruRU.lua
+++ b/Decursive/Localization/ruRU.lua
@@ -99,7 +99,6 @@ L["BINDING_NAME_DCRSKLIST"] = "Распечатка списка пропуск
L["BINDING_NAME_DCRSKSHOW"] = "Показать или скрыть список пропусков"
L["BLACK_LENGTH"] = "Секунд в чёрном списке : "
L["BLACKLISTED"] = "В чёрном списке"
-L["BLEED"] = "Кровотечение"
L["CHARM"] = "Подчинение"
L["CLASS_HUNTER"] = "Охотник"
L["CLEAR_PRIO"] = "О"
@@ -197,7 +196,6 @@ L["OPT_ANCHOR_DESC"] = "Отображать указатель пользова
L["OPT_AUTOHIDEMFS"] = "Автоскрытие"
L["OPT_AUTOHIDEMFS_DESC"] = "Выберите, когда скрывать МФИ"
L["OPT_BLACKLENTGH_DESC"] = "Установить продолжительность нахождения кого-либо в чёрном списке"
-L["OPT_BLEEDCHECK_DESC"] = "Если отмечено, вы сможете видеть и снимать эффекты кровотечения (CoA: заклинания вроде «Прижигания», снимающие механику кровотечения)"
L["OPT_BORDERTRANSP"] = "Прозрачность краёв"
L["OPT_BORDERTRANSP_DESC"] = "Установка прозрачности краёв"
L["OPT_CENTERTRANSP"] = "Прозрачность центра"
diff --git a/Decursive/Localization/zhCN.lua b/Decursive/Localization/zhCN.lua
index 29fc3cd..3aa5213 100644
--- a/Decursive/Localization/zhCN.lua
+++ b/Decursive/Localization/zhCN.lua
@@ -98,7 +98,6 @@ L["BINDING_NAME_DCRSKLIST"] = "显示忽略列表明细条目"
L["BINDING_NAME_DCRSKSHOW"] = "显示/隐藏 忽略列表"
L["BLACK_LENGTH"] = "黑名单持续时间: "
L["BLACKLISTED"] = "黑名单"
-L["BLEED"] = "流血"
L["CHARM"] = "魅惑"
L["CLASS_HUNTER"] = "猎人"
L["CLEAR_PRIO"] = "C"
@@ -192,7 +191,6 @@ L["OPT_ANCHOR_DESC"] = "设置自定义信息面板的定位点。"
L["OPT_AUTOHIDEMFS"] = "自动隐藏"
L["OPT_AUTOHIDEMFS_DESC"] = "选择何时自动隐藏微单元面板(MUF)"
L["OPT_BLACKLENTGH_DESC"] = "设置被暂时加入黑名单的玩家在名单中停留的时间。"
-L["OPT_BLEEDCHECK_DESC"] = "选中后你将可以查看和移除流血效果(CoA:如「灼烧术」等可清除流血机制的法术)"
L["OPT_BORDERTRANSP"] = "边框透明度"
L["OPT_BORDERTRANSP_DESC"] = "设置边框的透明度。"
L["OPT_CENTERTRANSP"] = "面板透明度"
diff --git a/Decursive/Localization/zhTW.lua b/Decursive/Localization/zhTW.lua
index f6cb448..cd2a6cc 100644
--- a/Decursive/Localization/zhTW.lua
+++ b/Decursive/Localization/zhTW.lua
@@ -97,7 +97,6 @@ L["BINDING_NAME_DCRSKLIST"] = "顯示忽略名單至聊天視窗"
L["BINDING_NAME_DCRSKSHOW"] = "開/關忽略名單"
L["BLACK_LENGTH"] = "停留在排除名單的時間: "
L["BLACKLISTED"] = "在排除名單"
-L["BLEED"] = "流血"
L["CHARM"] = "魅惑"
L["CLASS_HUNTER"] = "獵人"
L["CLEAR_PRIO"] = "C"
@@ -190,7 +189,6 @@ L["OPT_ANCHOR_DESC"] = "顯示自訂視窗的文字定位點。"
L["OPT_AUTOHIDEMFS"] = "自動隱藏"
L["OPT_AUTOHIDEMFS_DESC"] = "選擇什麼時候隱藏 MUF 視窗"
L["OPT_BLACKLENTGH_DESC"] = "設定一個人停留在排除名單中的時間。"
-L["OPT_BLEEDCHECK_DESC"] = "選取後你可以看見並移除流血效果(CoA:如「灼燒術」等可清除流血機制的法術)"
L["OPT_BORDERTRANSP"] = "邊框透明度"
L["OPT_BORDERTRANSP_DESC"] = "設定邊框的透明度。"
L["OPT_CENTERTRANSP"] = "中央透明度"
diff --git a/Decursive/Textures/BackDrop.blp b/Decursive/Textures/BackDrop.blp
deleted file mode 100644
index aee00f3..0000000
Binary files a/Decursive/Textures/BackDrop.blp and /dev/null differ
diff --git a/Decursive/Textures/BackDrop.tga b/Decursive/Textures/BackDrop.tga
new file mode 100644
index 0000000..c532d41
Binary files /dev/null and b/Decursive/Textures/BackDrop.tga differ
diff --git a/Decursive/Textures/GoldBorder.blp b/Decursive/Textures/GoldBorder.blp
deleted file mode 100644
index 4c0f30f..0000000
Binary files a/Decursive/Textures/GoldBorder.blp and /dev/null differ
diff --git a/Decursive/Textures/GoldBorder.tga b/Decursive/Textures/GoldBorder.tga
new file mode 100644
index 0000000..159a06e
Binary files /dev/null and b/Decursive/Textures/GoldBorder.tga differ
diff --git a/Decursive/iconOFF.blp b/Decursive/iconOFF.blp
deleted file mode 100644
index 8c37e65..0000000
Binary files a/Decursive/iconOFF.blp and /dev/null differ
diff --git a/Decursive/iconOFF.tga b/Decursive/iconOFF.tga
new file mode 100644
index 0000000..6207de6
Binary files /dev/null and b/Decursive/iconOFF.tga differ
diff --git a/Decursive/iconON.blp b/Decursive/iconON.blp
deleted file mode 100644
index 5c88fc0..0000000
Binary files a/Decursive/iconON.blp and /dev/null differ
diff --git a/Decursive/iconON.tga b/Decursive/iconON.tga
new file mode 100644
index 0000000..dfe7563
Binary files /dev/null and b/Decursive/iconON.tga differ
diff --git a/tools/build_zip.sh b/tools/build_zip.sh
deleted file mode 100755
index 45d1400..0000000
--- a/tools/build_zip.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env bash
-# Build per-addon zip artefacts from HEAD via git-archive.
-#
-# - Discovers top-level addon folders (Foo/Foo.toc).
-# - Re-creates dist/ each run.
-# - Always archives HEAD, so the working tree state is irrelevant.
-# - If more than one addon folder is present, also emits -all.zip
-# with every addon folder side-by-side at the zip root.
-# - When run inside Gitea Actions the working tree lives under a
-# per-job dir like /var/lib/act_runner/work/.../hostexecutor, so the
-# repo name comes from $GITHUB_REPOSITORY (set by the runner) and
-# only falls back to the toplevel basename for local invocations.
-set -euo pipefail
-
-root=$(git rev-parse --show-toplevel)
-cd "$root"
-
-# Gitea Actions sets GITHUB_REPOSITORY=owner/repo. The basename of
-# `git rev-parse --show-toplevel` inside the runner is the worker dir
-# (e.g. `hostexecutor`), which would name the bundle wrong.
-if [ -n "${GITHUB_REPOSITORY:-}" ]; then
- repo_name="${GITHUB_REPOSITORY##*/}"
-else
- repo_name=$(basename "$root")
-fi
-dist="$root/dist"
-
-# Find Foo/Foo.toc pairs at depth 1; ignore libs nested deeper.
-addons=()
-while IFS= read -r toc; do
- dir=$(dirname "$toc")
- folder=$(basename "$dir")
- base=$(basename "$toc" .toc)
- # Accept Foo.toc and Foo_Wrath.toc style flavour variants; folder must match
- # at least one toc basename prefix (Foo).
- case "$base" in
- "$folder"|"$folder"_*) addons+=("$folder") ;;
- esac
-done < <(command find . -mindepth 2 -maxdepth 2 -type f -name '*.toc' | sed 's|^\./||' | sort)
-
-# Dedupe (a folder with Foo.toc + Foo_Wrath.toc shows up twice).
-if [ ${#addons[@]} -gt 0 ]; then
- mapfile -t addons < <(printf '%s\n' "${addons[@]}" | awk '!seen[$0]++')
-fi
-
-if [ ${#addons[@]} -eq 0 ]; then
- echo "no addon folders found (looking for */Foo.toc with matching folder name)" >&2
- exit 1
-fi
-
-rm -rf "$dist"
-mkdir -p "$dist"
-
-for folder in "${addons[@]}"; do
- out="$dist/$folder.zip"
- # No --prefix: the folder already sits at the repo root, so git-archive
- # emits entries as /... which is exactly what
- # Interface/AddOns/ expects after extraction.
- git archive HEAD --format=zip -o "$out" -- "$folder"
- echo "built dist/$folder.zip"
-done
-
-# Combined bundle only makes sense when there are multiple addons.
-if [ ${#addons[@]} -gt 1 ]; then
- tmp=$(mktemp -d)
- trap 'rm -rf "$tmp"' EXIT
- git archive HEAD --format=tar -- "${addons[@]}" | tar -x -C "$tmp"
- out="$dist/$repo_name-all.zip"
- ( cd "$tmp" && zip -qr "$out" "${addons[@]}" )
- echo "built dist/$repo_name-all.zip"
-fi