├── .editorconfig
├── .github
└── workflows
│ └── release.yml
├── .gitignore
├── .luarc.json
├── .pkgmeta
├── CHANGELOG.md
├── Checklist.lua
├── Constants.lua
├── Core.lua
├── Data.lua
├── Interface.lua
├── Libs
├── AceAddon-3.0
│ ├── AceAddon-3.0.lua
│ └── AceAddon-3.0.xml
├── AceBucket-3.0
│ ├── AceBucket-3.0.lua
│ └── AceBucket-3.0.xml
├── AceComm-3.0
│ ├── AceComm-3.0.lua
│ ├── AceComm-3.0.xml
│ └── ChatThrottleLib.lua
├── AceConfig-3.0
│ ├── AceConfig-3.0.lua
│ ├── AceConfig-3.0.xml
│ ├── AceConfigCmd-3.0
│ │ ├── AceConfigCmd-3.0.lua
│ │ └── AceConfigCmd-3.0.xml
│ ├── AceConfigDialog-3.0
│ │ ├── AceConfigDialog-3.0.lua
│ │ └── AceConfigDialog-3.0.xml
│ └── AceConfigRegistry-3.0
│ │ ├── AceConfigRegistry-3.0.lua
│ │ └── AceConfigRegistry-3.0.xml
├── AceConsole-3.0
│ ├── AceConsole-3.0.lua
│ └── AceConsole-3.0.xml
├── AceDB-3.0
│ ├── AceDB-3.0.lua
│ └── AceDB-3.0.xml
├── AceEvent-3.0
│ ├── AceEvent-3.0.lua
│ └── AceEvent-3.0.xml
├── AceGUI-3.0
│ ├── AceGUI-3.0.lua
│ ├── AceGUI-3.0.xml
│ └── widgets
│ │ ├── AceGUIContainer-BlizOptionsGroup.lua
│ │ ├── AceGUIContainer-DropDownGroup.lua
│ │ ├── AceGUIContainer-Frame.lua
│ │ ├── AceGUIContainer-InlineGroup.lua
│ │ ├── AceGUIContainer-ScrollFrame.lua
│ │ ├── AceGUIContainer-SimpleGroup.lua
│ │ ├── AceGUIContainer-TabGroup.lua
│ │ ├── AceGUIContainer-TreeGroup.lua
│ │ ├── AceGUIContainer-Window.lua
│ │ ├── AceGUIWidget-Button.lua
│ │ ├── AceGUIWidget-CheckBox.lua
│ │ ├── AceGUIWidget-ColorPicker.lua
│ │ ├── AceGUIWidget-DropDown-Items.lua
│ │ ├── AceGUIWidget-DropDown.lua
│ │ ├── AceGUIWidget-EditBox.lua
│ │ ├── AceGUIWidget-Heading.lua
│ │ ├── AceGUIWidget-Icon.lua
│ │ ├── AceGUIWidget-InteractiveLabel.lua
│ │ ├── AceGUIWidget-Keybinding.lua
│ │ ├── AceGUIWidget-Label.lua
│ │ ├── AceGUIWidget-MultiLineEditBox.lua
│ │ └── AceGUIWidget-Slider.lua
├── AceTimer-3.0
│ ├── AceTimer-3.0.lua
│ └── AceTimer-3.0.xml
├── CallbackHandler-1.0
│ ├── CallbackHandler-1.0.lua
│ └── CallbackHandler-1.0.xml
├── LibDBIcon-1.0
│ ├── LibDBIcon-1.0.lua
│ └── lib.xml
├── LibDataBroker-1.1
│ └── LibDataBroker-1.1.lua
└── LibStub
│ └── LibStub.lua
├── Main.lua
├── Media
├── Icon.blp
├── Icon.png
├── Icon.svg
├── Icon_Characters.blp
├── Icon_Characters.png
├── Icon_Checklist.blp
├── Icon_Checklist.png
├── Icon_Close.blp
├── Icon_Close.png
├── Icon_Columns.blp
├── Icon_Columns.png
├── Icon_Settings.blp
├── Icon_Settings.png
├── Icon_Toggle.blp
├── Icon_Toggle.png
├── Logo.jpg
├── Logo.png
├── Logo.psd
├── Screenshot1.png
├── Screenshot2.png
├── Screenshot3.png
├── Screenshot4.png
├── Screenshot5.png
├── Screenshot6.png
└── ScreenshotOld.png
├── README.md
├── Types.lua
├── Utils.lua
└── WeeklyKnowledge.toc
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_size = 2
6 | indent_style = space
7 | insert_final_newline = true
8 |
9 | [*.lua]
10 | align_array_table = true
11 | align_call_args = true
12 | align_continuous_rect_table_field = true
13 | continuation_indent = 2
14 | indent_size = 2
15 | max_line_length = unset
16 | quote_style = double
17 | space_around_table_field_list = false
18 | space_before_attribute = false
19 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Package and release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v*"
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Git good
14 | uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0
17 |
18 | - name: Package and release
19 | uses: BigWigsMods/packager@master
20 | env:
21 | CF_API_KEY: ${{ secrets.CF_API_KEY }}
22 | GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
23 | WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }}
24 | WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }}
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | /docs
3 |
--------------------------------------------------------------------------------
/.luarc.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtime.version": "Lua 5.1",
3 | "workspace.ignoreDir": [
4 | ".vscode",
5 | "Libs/"
6 | ],
7 | "diagnostics.disable": [
8 | "deprecated",
9 | "duplicate-set-field",
10 | "inject-field",
11 | "undefined-field"
12 | ],
13 | "diagnostics.globals": [
14 | "_G",
15 | "ACCEPT",
16 | "AddonCompartmentFrame",
17 | "C_ChallengeMode",
18 | "C_ClassColor",
19 | "C_Container",
20 | "C_DateAndTime",
21 | "C_MythicPlus",
22 | "C_PlayerInfo",
23 | "C_Timer",
24 | "C_WeeklyRewards",
25 | "CANCEL",
26 | "CHARACTER",
27 | "ChatEdit_GetActiveWindow",
28 | "ChatEdit_InsertLink",
29 | "ChatFontNormal",
30 | "ChatFrame_OpenChat",
31 | "CLOSE",
32 | "ColorPickerFrame",
33 | "CreateColor",
34 | "CreateColorFromHexString",
35 | "CreateFrame",
36 | "date",
37 | "DEFAULT_CHAT_FRAME",
38 | "DevTools_Dump",
39 | "DUNGEON_SCORE_BEST_AFFIX",
40 | "DUNGEON_SCORE_LINK",
41 | "DUNGEON_SCORE_OVERTIME_TIME",
42 | "DUNGEON_SCORE_TOTAL_SCORE",
43 | "EJ_GetEncounterInfoByIndex",
44 | "EJ_SelectInstance",
45 | "Enum",
46 | "EPIC_PURPLE_COLOR",
47 | "floor",
48 | "FONT_COLOR_CODE_CLOSE",
49 | "format",
50 | "GameFontDisableSmall",
51 | "GameFontHighlight",
52 | "GameFontHighlightLarge",
53 | "GameFontHighlightSmall",
54 | "GameFontNormal",
55 | "GameFontNormalSmall",
56 | "GameTooltip_AddBlankLineToTooltip",
57 | "GameTooltip_AddColoredLine",
58 | "GameTooltip_AddNormalLine",
59 | "GameTooltip",
60 | "GetAverageItemLevel",
61 | "GetDetailedItemLevelInfo",
62 | "GetDifficultyInfo",
63 | "GetItemLevelColor",
64 | "GetNumSavedInstances",
65 | "GetRealmName",
66 | "GetSavedInstanceChatLink",
67 | "GetSavedInstanceEncounterInfo",
68 | "GetSavedInstanceInfo",
69 | "GetScreenWidth",
70 | "GetServerTime",
71 | "GREAT_VAULT_IMPROVE_REWARD",
72 | "GREAT_VAULT_REWARDS_MYTHIC_COMPLETED_FIRST",
73 | "GREAT_VAULT_REWARDS_MYTHIC_COMPLETED_SECOND",
74 | "GREAT_VAULT_REWARDS_MYTHIC_COMPLETED_THIRD",
75 | "GREAT_VAULT_REWARDS_MYTHIC_IMPROVE",
76 | "GREAT_VAULT_REWARDS_MYTHIC_INCOMPLETE",
77 | "GREAT_VAULT_REWARDS_WAITING",
78 | "GREEN_FONT_COLOR",
79 | "hash_SlashCmdList",
80 | "HIGHLIGHT_FONT_COLOR_CODE",
81 | "HIGHLIGHT_FONT_COLOR",
82 | "InterfaceOptions_AddCategory",
83 | "ipairs",
84 | "IsModifiedClick",
85 | "IsSecureCmd",
86 | "LEGENDARY_ORANGE_COLOR",
87 | "LIGHTGRAY_FONT_COLOR",
88 | "LinkUtil",
89 | "math",
90 | "MYTHIC_PLUS_POWER_LEVEL",
91 | "NORMAL_FONT_COLOR_CODE",
92 | "NORMAL_FONT_COLOR",
93 | "NOT_BOUND",
94 | "NUM_BAG_SLOTS",
95 | "NUM_CHAT_WINDOWS",
96 | "OKAY",
97 | "OpacitySliderFrame",
98 | "pairs",
99 | "PAPERDOLLFRAME_TOOLTIP_FORMAT",
100 | "RARE_BLUE_COLOR",
101 | "RequestRaidInfo",
102 | "SECONDS_PER_HOUR",
103 | "SecondsToClock",
104 | "SELECTED_CHAT_FRAME",
105 | "SetDesaturation",
106 | "Settings",
107 | "SlashCmdList",
108 | "STAT_AVERAGE_ITEM_LEVEL_EQUIPPED",
109 | "STAT_AVERAGE_ITEM_LEVEL_TOOLTIP",
110 | "STAT_AVERAGE_ITEM_LEVEL",
111 | "STAT_AVERAGE_PVP_ITEM_LEVEL",
112 | "string",
113 | "strsplit",
114 | "strtrim",
115 | "table",
116 | "time",
117 | "ToggleDropDownMenu",
118 | "tonumber",
119 | "tostring",
120 | "type",
121 | "UIDropDownMenu_AddButton",
122 | "UIDropDownMenu_Initialize",
123 | "UIDropDownMenu_SetWidth",
124 | "UIParent",
125 | "UISpecialFrames",
126 | "UNCOMMON_GREEN_COLOR",
127 | "UnitClass",
128 | "UnitFactionGroup",
129 | "UnitGUID",
130 | "UnitLevel",
131 | "UnitName",
132 | "UnitRace",
133 | "unpack",
134 | "WHITE_FONT_COLOR",
135 | "wipe",
136 | "WrapTextInColorCode",
137 | "LibStub",
138 | "WeeklyRewardsUtil",
139 | "GREAT_VAULT_REWARDS_HEROIC_IMPROVE",
140 | "INSTANCE_RESET_SUCCESS",
141 | "RESET_INSTANCES",
142 | "INSTANCE_RESET_FAILED",
143 | "INSTANCE_RESET_FAILED_OFFLINE",
144 | "INSTANCE_RESET_FAILED_ZONING",
145 | "STANDARD_TEXT_FONT",
146 | "UIDropDownMenuButton_OpenColorPicker",
147 | "CreateSimpleTextureMarkup",
148 | "ITEM_UPGRADE_TOOLTIP_FORMAT_STRING",
149 | "RED_FONT_COLOR",
150 | "PVPUtil",
151 | "GetProfessions",
152 | "C_Traits",
153 | "IsPlayerSpell",
154 | "C_QuestLog",
155 | "C_ProfSpecs",
156 | "C_Calendar",
157 | "GetProfessionInfo",
158 | "MenuUtil",
159 | "GameTooltip_SetTitle",
160 | "ChatFrame_OpenChat",
161 | "ChatEdit_InsertLink",
162 | "HelpTip",
163 | "MAP_PIN_HYPERLINK",
164 | "UiMapPoint",
165 | "CreateSimpleTextureMarkup"
166 | ]
167 | }
168 |
--------------------------------------------------------------------------------
/.pkgmeta:
--------------------------------------------------------------------------------
1 | package-as: WeeklyKnowledge
2 |
3 | enable-nolib-creation: no
4 |
5 | ignore:
6 | - "*.png"
7 | - "*.jpg"
8 | - "*.psd"
9 |
10 | manual-changelog:
11 | filename: CHANGELOG.md
12 | markup-type: markdown
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## v1.1.9 - 2025-03-13
4 |
5 | ### Updated
6 |
7 | - Catch-Up objectives in the Checklist no longer include knowledge points available for the current week (Thanks to [Belazor](https://github.com/belazor-wow/))
8 |
9 | ### Fixed
10 |
11 | - Resolved an issue where old characters without Catch-Up currency info were causing errors
12 |
13 | ## v1.1.8 - 2025-02-26
14 |
15 | ### Added
16 |
17 | - Added Catch-Up objectives to the Checklist (Thanks to [Belazor](https://github.com/belazor-wow/))
18 | - Added addon category for the new AddOn List. Credit: Warcraft Wiki
19 |
20 | ### Updated
21 |
22 | - Improved the performance of the addon when not shown on screen
23 | - Updated the TOC number to support patch 11.1
24 |
25 | ### Fixed
26 |
27 | - Fixed a bug related to the Darkmoon Faire (Thanks to [Belazor](https://github.com/belazor-wow/))
28 |
29 | ## v1.1.7 - 2024-10-16
30 |
31 | ### Added
32 |
33 | - Introduced a new Catch-Up column. Feedback is greatly appreciated!
34 |
35 | ### Updated
36 |
37 | - Window frames can now be partially dragged off-screen to the sides and bottom.
38 |
39 | ### Fixed
40 |
41 | - Resolved an issue where ghost characters were appearing on the character list.
42 |
43 | ## v1.1.6 - 2024-09-16
44 |
45 | _Please note: You will need to log in to your characters again to apply the following changes._
46 |
47 | ### Added
48 |
49 | - Introduced a column indicator displaying unspent knowledge points
50 | - Added a new tooltip for the Knowledge column
51 | - The new Knowledge tooltip now shows an overview of spent, unspent, and maximum knowledge points
52 | - Added a profession specialization overview to the Knowledge tooltip
53 |
54 | ### Fixed
55 |
56 | - Resolved an issue where knowledge points would increase after every reload
57 | - Fixed a bug that prevented profession skill levels from updating during gameplay
58 |
59 | ## v1.1.5 - 2024-09-15
60 |
61 | ### Added
62 |
63 | - Added a new Character setting for hiding unused professions
64 |
65 | ## v1.1.4 - 2024-09-11
66 |
67 | ### Fixed
68 |
69 | - Fixed a bug with unused/invalid characters causing errors
70 | - Fixed a bug with characters not showing up in the main window or dropdown
71 |
72 | ## v1.1.3 - 2024-09-09
73 |
74 | ### Added
75 |
76 | - Introduced a new Checklist setting: "Hide all uniques"
77 | - Added a Checklist setting for hiding vendor-specific uniques
78 | - Integrated support for TomTom waypoints within the Checklist window
79 | - Right clicking the minimap icon will now open the Checklist window
80 |
81 | ### Updated
82 |
83 | - Expanded and improved detailed descriptions for many world uniques
84 | - The Darkmoon Faire column now automatically hides when the event is inactive
85 | - Adjusted scrolling behavior to move by 2 rows for smoother navigation
86 | - Redesigned scrollbars to be more visible, user-friendly, and less prone to bugs
87 | - Addon windows now remain behind other UI elements unless selected
88 |
89 | ### Fixed
90 |
91 | - Darkmoon Faire objectives will now correctly disappear from the checklist when the event is inactive
92 | - Resolved an old issue with character sorting
93 | - Fixed an issue where checklist waypoint icons weren't displaying properly for certain players
94 |
95 | ## v1.1.2 - 2024-09-08
96 |
97 | ### Added
98 |
99 | - Added a new checklist column: Location
100 |
101 | ### Updated
102 |
103 | - Added detailed descriptions to most world uniques
104 |
105 | ### Fixed
106 |
107 | - Fixed an incorect location for Jewel-Etched Tailoring Notes (Thanks Shikimi)
108 | - Fixed a major issue of "ADDON_ACTION_BLOCKED" in certain situations while in combat (A massive thanks to Linaori, Numy and Meo 🦆 from the WoWUIDev Discord server for helping with the investigation and solution)
109 |
110 | ## v1.1.1 - 2024-09-07
111 |
112 | ### Fixed
113 |
114 | - Adjusted the requirements for the Darkmoon Faire quest "Eyes on the Prizes" (Thanks masterkain)
115 |
116 | ## v1.1.0 - 2024-09-07
117 |
118 | A big shout-out to the WoWUIDev Discord community for all the guidance, help and testing. You rock!
119 | If you encounter a bug or incorrect data, please don't hesitate to reach out. Write a comment or visit the GitHub source :-)
120 | Thank you for your support.
121 |
122 | ### Added
123 |
124 | - Added a new Checklist window
125 | - Added map/location sources to objectives
126 | - Added hints on how to complete objectives
127 | - Added waypoints for objectives
128 | - Added requirements for objectives
129 | - You can now see the items missing/needed in the main window tooltips
130 | - New Setting: Show/hide window border
131 |
132 | ### Updated
133 |
134 | - Updated a couple of tooltip descriptions
135 |
136 | ### Fixed
137 |
138 | - Fixed a bug with Darkmoon values not showing on login (Thansk @Lombra)
139 | - Fixed a bug with ghost characters showing up on the list (scary!)
140 | - Scrollbars no longer overlap the column headers
141 | - Background color of column headers are no longer just grey if window color is different
142 | - Fixed a bug with transparent background colors not being transparent
143 |
144 | ## v1.0.4 - 2024-09-04
145 |
146 | ### Fixed
147 |
148 | - Fixed a bug with weekly reset. Character progress should now be reset. A big shout-out to the player community in the comments for showing interest in helping fix these issues. You are much appreciated!
149 |
150 | ## v1.0.3 - 2024-09-01
151 |
152 | ### Added
153 |
154 | - New column: Realm
155 | - New setting: You can now show/hide characters
156 | - New setting: You can now show/hide columns
157 | - New setting: You can now show/hide the minimap icon
158 | - New setting: You can now lock the minimap icon
159 | - New setting: You can now scale the main window
160 | - New setting: You can now change the base color of the main window
161 |
162 | ### Updated
163 |
164 | - Addon interface has been fully rewritten with a new design
165 | - Column sorting is disabled for now. Will be back soon!
166 | - Characters are sorted by most recent activity for now.
167 | - Tooltips now show whether you are finding items or doing quests
168 |
169 | ### Fixed
170 |
171 | - Addon now updates when you learn/unlearn a TWW profession
172 | - Darkmoon Faire column is now visible
173 | - Characters with old expansion professions are no longer saved/shown
174 | - Fixed incorrect Darkmoon KP values
175 | - The addon performance has been improved using 100x less memory
176 | - Weekly progress will now reset for all characters on weekly reset
177 | - Added missing quest from the Enchanting trainer
178 | - Knowledge Points are now calculated properly for Trainer quests
179 |
180 | ## v1.0.2 - 2024-08-28
181 |
182 | ### Added
183 |
184 | - You can now close the window with the Escape key
185 | - Added new progress tooltips with knowledge points
186 | - Added a new command to show/hide the minimap icon
187 |
188 | ### Updated
189 |
190 | - Added colors to the header column
191 | - Renamed "Work Order" to "Artisan"
192 | - Rewritten column descriptions to clarify the sources
193 | - Updated the addon description
194 |
195 | ## v1.0.1 - 2024-08-27
196 |
197 | ### Fixed
198 |
199 | - Fixed a bug with missing libraries - Thanks @IvViral
200 |
201 | ## v1.0.0 - 2024-08-27
202 |
203 | - First release <3
204 |
--------------------------------------------------------------------------------
/Constants.lua:
--------------------------------------------------------------------------------
1 | ---@type string
2 | local addonName = select(1, ...)
3 | ---@class WK_Addon
4 | local addon = select(2, ...)
5 |
6 | ---@class WK_Constants
7 | local Constants = {}
8 | addon.Constants = Constants
9 |
10 | Constants.TITLEBAR_HEIGHT = 30
11 | Constants.TABLE_ROW_HEIGHT = 24
12 | Constants.TABLE_HEADER_HEIGHT = 32
13 | Constants.TABLE_CELL_PADDING = 8
14 | Constants.MAX_WINDOW_HEIGHT = 500
15 |
--------------------------------------------------------------------------------
/Core.lua:
--------------------------------------------------------------------------------
1 | ---@type string
2 | local addonName = select(1, ...)
3 | ---@class WK_Addon
4 | local addon = select(2, ...)
5 |
6 | local Data = addon.Data
7 | local Main = addon.Main
8 | local Checklist = addon.Checklist
9 | local LibDataBroker = LibStub("LibDataBroker-1.1")
10 | local LibDBIcon = LibStub("LibDBIcon-1.0")
11 |
12 | local Core = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceTimer-3.0", "AceEvent-3.0", "AceBucket-3.0")
13 | addon.Core = Core
14 |
15 | _G.WeeklyKnowledge = addon
16 |
17 | function Core:Render()
18 | Main:Render()
19 | Checklist:Render()
20 | end
21 |
22 | function Core:OnInitialize()
23 | _G["BINDING_NAME_WEEKLYKNOWLEDGE"] = "Show/Hide the window"
24 | self:RegisterChatCommand("wk", function() Main:ToggleWindow() end)
25 | self:RegisterChatCommand("weeklyknowledge", function() Main:ToggleWindow() end)
26 |
27 | Data:InitDB()
28 | Data:MigrateDB()
29 | if Data:TaskWeeklyReset() then
30 | self:Print("Weekly Reset: Good job! Progress of your characters have been reset for a new week.")
31 | end
32 |
33 | local WKLDB = LibDataBroker:NewDataObject(addonName, {
34 | label = addonName,
35 | type = "launcher",
36 | icon = "Interface/AddOns/WeeklyKnowledge/Media/Icon.blp",
37 | OnClick = function(...)
38 | local _, b = ...
39 | if b and b == "RightButton" then
40 | Checklist:ToggleWindow()
41 | else
42 | Main:ToggleWindow()
43 | end
44 | end,
45 | OnTooltipShow = function(tooltip)
46 | tooltip:SetText(addonName, 1, 1, 1)
47 | tooltip:AddLine("|cff00ff00Left click|r to open WeeklyKnowledge.", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
48 | tooltip:AddLine("|cff00ff00Right click|r to open the Checklist.", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
49 | local dragText = "|cff00ff00Drag|r to move this icon"
50 | if Data.db.global.minimap.lock then
51 | dragText = dragText .. " |cffff0000(locked)|r"
52 | end
53 | tooltip:AddLine(dragText .. ".", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
54 | end
55 | })
56 | LibDBIcon:Register(addonName, WKLDB, Data.db.global.minimap)
57 | LibDBIcon:AddButtonToCompartment(addonName)
58 |
59 | self:Render()
60 | end
61 |
62 | function Core:OnEnable()
63 | self:RegisterEvent("PLAYER_REGEN_DISABLED", function()
64 | Data.cache.inCombat = true
65 | self:Render()
66 | end)
67 | self:RegisterEvent("PLAYER_REGEN_ENABLED", function()
68 | Data.cache.inCombat = false
69 | self:Render()
70 | end)
71 | self:RegisterBucketEvent(
72 | {
73 | "ACTIVE_TALENT_GROUP_CHANGED",
74 | "BAG_UPDATE_DELAYED",
75 | "CHAT_MSG_LOOT",
76 | "ITEM_COUNT_CHANGED",
77 | "PLAYER_SPECIALIZATION_CHANGED",
78 | "PLAYER_TALENT_UPDATE",
79 | "QUEST_COMPLETE",
80 | "QUEST_TURNED_IN",
81 | "SKILL_LINES_CHANGED",
82 | "TRAIT_CONFIG_UPDATED",
83 | "UNIT_INVENTORY_CHANGED",
84 | },
85 | 3,
86 | function()
87 | Data.cache.weeklyProgress = {}
88 | Data:ScanCharacter()
89 | self:Render()
90 | end
91 | )
92 |
93 | self:RegisterBucketEvent({"CALENDAR_UPDATE_EVENT_LIST",}, 1, function()
94 | Data.cache.weeklyProgress = {}
95 | Data:ScanCalendar()
96 | self:Render()
97 | end)
98 | local currentCalendarTime = C_DateAndTime.GetCurrentCalendarTime()
99 | C_Calendar.SetAbsMonth(currentCalendarTime.month, currentCalendarTime.year)
100 | C_Calendar.OpenCalendar()
101 |
102 | Data:ScanCharacter()
103 | self:Render()
104 | end
105 |
106 | function Core:OnDisable()
107 | self:UnregisterAllEvents()
108 | self:UnregisterAllBuckets()
109 | end
110 |
--------------------------------------------------------------------------------
/Libs/AceAddon-3.0/AceAddon-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceBucket-3.0/AceBucket-3.0.lua:
--------------------------------------------------------------------------------
1 | --- A bucket to catch events in. **AceBucket-3.0** provides throttling of events that fire in bursts and
2 | -- your addon only needs to know about the full burst.
3 | --
4 | -- This Bucket implementation works as follows:\\
5 | -- Initially, no schedule is running, and its waiting for the first event to happen.\\
6 | -- The first event will start the bucket, and get the scheduler running, which will collect all
7 | -- events in the given interval. When that interval is reached, the bucket is pushed to the
8 | -- callback and a new schedule is started. When a bucket is empty after its interval, the scheduler is
9 | -- stopped, and the bucket is only listening for the next event to happen, basically back in its initial state.
10 | --
11 | -- In addition, the buckets collect information about the "arg1" argument of the events that fire, and pass those as a
12 | -- table to your callback. This functionality was mostly designed for the UNIT_* events.\\
13 | -- The table will have the different values of "arg1" as keys, and the number of occurances as their value, e.g.\\
14 | -- { ["player"] = 2, ["target"] = 1, ["party1"] = 1 }
15 | --
16 | -- **AceBucket-3.0** can be embeded into your addon, either explicitly by calling AceBucket:Embed(MyAddon) or by
17 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
18 | -- and can be accessed directly, without having to explicitly call AceBucket itself.\\
19 | -- It is recommended to embed AceBucket, otherwise you'll have to specify a custom `self` on all calls you
20 | -- make into AceBucket.
21 | -- @usage
22 | -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("BucketExample", "AceBucket-3.0")
23 | --
24 | -- function MyAddon:OnEnable()
25 | -- -- Register a bucket that listens to all the HP related events,
26 | -- -- and fires once per second
27 | -- self:RegisterBucketEvent({"UNIT_HEALTH", "UNIT_MAXHEALTH"}, 1, "UpdateHealth")
28 | -- end
29 | --
30 | -- function MyAddon:UpdateHealth(units)
31 | -- if units.player then
32 | -- print("Your HP changed!")
33 | -- end
34 | -- end
35 | -- @class file
36 | -- @name AceBucket-3.0.lua
37 | -- @release $Id: AceBucket-3.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $
38 |
39 | local MAJOR, MINOR = "AceBucket-3.0", 4
40 | local AceBucket, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
41 |
42 | if not AceBucket then return end -- No Upgrade needed
43 |
44 | AceBucket.buckets = AceBucket.buckets or {}
45 | AceBucket.embeds = AceBucket.embeds or {}
46 |
47 | -- the libraries will be lazyly bound later, to avoid errors due to loading order issues
48 | local AceEvent, AceTimer
49 |
50 | -- Lua APIs
51 | local tconcat = table.concat
52 | local type, next, pairs, select = type, next, pairs, select
53 | local tonumber, tostring, rawset = tonumber, tostring, rawset
54 | local assert, loadstring, error = assert, loadstring, error
55 |
56 | local bucketCache = setmetatable({}, {__mode='k'})
57 |
58 | --[[
59 | xpcall safecall implementation
60 | ]]
61 | local xpcall = xpcall
62 |
63 | local function errorhandler(err)
64 | return geterrorhandler()(err)
65 | end
66 |
67 | local function safecall(func, ...)
68 | if func then
69 | return xpcall(func, errorhandler, ...)
70 | end
71 | end
72 |
73 | -- FireBucket ( bucket )
74 | --
75 | -- send the bucket to the callback function and schedule the next FireBucket in interval seconds
76 | local function FireBucket(bucket)
77 | local received = bucket.received
78 |
79 | -- we dont want to fire empty buckets
80 | if next(received) ~= nil then
81 | local callback = bucket.callback
82 | if type(callback) == "string" then
83 | safecall(bucket.object[callback], bucket.object, received)
84 | else
85 | safecall(callback, received)
86 | end
87 |
88 | for k in pairs(received) do
89 | received[k] = nil
90 | end
91 |
92 | -- if the bucket was not empty, schedule another FireBucket in interval seconds
93 | bucket.timer = AceTimer.ScheduleTimer(bucket, FireBucket, bucket.interval, bucket)
94 | else -- if it was empty, clear the timer and wait for the next event
95 | bucket.timer = nil
96 | end
97 | end
98 |
99 | -- BucketHandler ( event, arg1 )
100 | --
101 | -- callback func for AceEvent
102 | -- stores arg1 in the received table, and schedules the bucket if necessary
103 | local function BucketHandler(self, event, arg1)
104 | if arg1 == nil then
105 | arg1 = "nil"
106 | end
107 |
108 | self.received[arg1] = (self.received[arg1] or 0) + 1
109 |
110 | -- if we are not scheduled yet, start a timer on the interval for our bucket to be cleared
111 | if not self.timer then
112 | self.timer = AceTimer.ScheduleTimer(self, FireBucket, self.interval, self)
113 | end
114 | end
115 |
116 | -- RegisterBucket( event, interval, callback, isMessage )
117 | --
118 | -- event(string or table) - the event, or a table with the events, that this bucket listens to
119 | -- interval(int) - time between bucket fireings
120 | -- callback(func or string) - function pointer, or method name of the object, that gets called when the bucket is cleared
121 | -- isMessage(boolean) - register AceEvent Messages instead of game events
122 | local function RegisterBucket(self, event, interval, callback, isMessage)
123 | -- try to fetch the librarys
124 | if not AceEvent or not AceTimer then
125 | AceEvent = LibStub:GetLibrary("AceEvent-3.0", true)
126 | AceTimer = LibStub:GetLibrary("AceTimer-3.0", true)
127 | if not AceEvent or not AceTimer then
128 | error(MAJOR .. " requires AceEvent-3.0 and AceTimer-3.0", 3)
129 | end
130 | end
131 |
132 | if type(event) ~= "string" and type(event) ~= "table" then error("Usage: RegisterBucket(event, interval, callback): 'event' - string or table expected.", 3) end
133 | if not callback then
134 | if type(event) == "string" then
135 | callback = event
136 | else
137 | error("Usage: RegisterBucket(event, interval, callback): cannot omit callback when event is not a string.", 3)
138 | end
139 | end
140 | if not tonumber(interval) then error("Usage: RegisterBucket(event, interval, callback): 'interval' - number expected.", 3) end
141 | if type(callback) ~= "string" and type(callback) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - string or function or nil expected.", 3) end
142 | if type(callback) == "string" and type(self[callback]) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - method not found on target object.", 3) end
143 |
144 | local bucket = next(bucketCache)
145 | if bucket then
146 | bucketCache[bucket] = nil
147 | else
148 | bucket = { handler = BucketHandler, received = {} }
149 | end
150 | bucket.object, bucket.callback, bucket.interval = self, callback, tonumber(interval)
151 |
152 | local regFunc = isMessage and AceEvent.RegisterMessage or AceEvent.RegisterEvent
153 |
154 | if type(event) == "table" then
155 | for _,e in pairs(event) do
156 | regFunc(bucket, e, "handler")
157 | end
158 | else
159 | regFunc(bucket, event, "handler")
160 | end
161 |
162 | local handle = tostring(bucket)
163 | AceBucket.buckets[handle] = bucket
164 |
165 | return handle
166 | end
167 |
168 | --- Register a Bucket for an event (or a set of events)
169 | -- @param event The event to listen for, or a table of events.
170 | -- @param interval The Bucket interval (burst interval)
171 | -- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
172 | -- @return The handle of the bucket (for unregistering)
173 | -- @usage
174 | -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
175 | -- MyAddon:RegisterBucketEvent("BAG_UPDATE", 0.2, "UpdateBags")
176 | --
177 | -- function MyAddon:UpdateBags()
178 | -- -- do stuff
179 | -- end
180 | function AceBucket:RegisterBucketEvent(event, interval, callback)
181 | return RegisterBucket(self, event, interval, callback, false)
182 | end
183 |
184 | --- Register a Bucket for an AceEvent-3.0 addon message (or a set of messages)
185 | -- @param message The message to listen for, or a table of messages.
186 | -- @param interval The Bucket interval (burst interval)
187 | -- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
188 | -- @return The handle of the bucket (for unregistering)
189 | -- @usage
190 | -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
191 | -- MyAddon:RegisterBucketEvent("SomeAddon_InformationMessage", 0.2, "ProcessData")
192 | --
193 | -- function MyAddon:ProcessData()
194 | -- -- do stuff
195 | -- end
196 | function AceBucket:RegisterBucketMessage(message, interval, callback)
197 | return RegisterBucket(self, message, interval, callback, true)
198 | end
199 |
200 | --- Unregister any events and messages from the bucket and clear any remaining data.
201 | -- @param handle The handle of the bucket as returned by RegisterBucket*
202 | function AceBucket:UnregisterBucket(handle)
203 | local bucket = AceBucket.buckets[handle]
204 | if bucket then
205 | AceEvent.UnregisterAllEvents(bucket)
206 | AceEvent.UnregisterAllMessages(bucket)
207 |
208 | -- clear any remaining data in the bucket
209 | for k in pairs(bucket.received) do
210 | bucket.received[k] = nil
211 | end
212 |
213 | if bucket.timer then
214 | AceTimer.CancelTimer(bucket, bucket.timer)
215 | bucket.timer = nil
216 | end
217 |
218 | AceBucket.buckets[handle] = nil
219 | -- store our bucket in the cache
220 | bucketCache[bucket] = true
221 | end
222 | end
223 |
224 | --- Unregister all buckets of the current addon object (or custom "self").
225 | function AceBucket:UnregisterAllBuckets()
226 | -- hmm can we do this more efficient? (it is not done often so shouldn't matter much)
227 | for handle, bucket in pairs(AceBucket.buckets) do
228 | if bucket.object == self then
229 | AceBucket.UnregisterBucket(self, handle)
230 | end
231 | end
232 | end
233 |
234 |
235 |
236 | -- embedding and embed handling
237 | local mixins = {
238 | "RegisterBucketEvent",
239 | "RegisterBucketMessage",
240 | "UnregisterBucket",
241 | "UnregisterAllBuckets",
242 | }
243 |
244 | -- Embeds AceBucket into the target object making the functions from the mixins list available on target:..
245 | -- @param target target object to embed AceBucket in
246 | function AceBucket:Embed( target )
247 | for _, v in pairs( mixins ) do
248 | target[v] = self[v]
249 | end
250 | self.embeds[target] = true
251 | return target
252 | end
253 |
254 | function AceBucket:OnEmbedDisable( target )
255 | target:UnregisterAllBuckets()
256 | end
257 |
258 | for addon in pairs(AceBucket.embeds) do
259 | AceBucket:Embed(addon)
260 | end
261 |
--------------------------------------------------------------------------------
/Libs/AceBucket-3.0/AceBucket-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceComm-3.0/AceComm-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceComm-3.0** allows you to send messages of unlimited length over the addon comm channels.
2 | -- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
3 | -- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
4 | --
5 | -- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceComm itself.\\
8 | -- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceComm.
10 | -- @class file
11 | -- @name AceComm-3.0
12 | -- @release $Id: AceComm-3.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $
13 |
14 | --[[ AceComm-3.0
15 |
16 | TODO: Time out old data rotting around from dead senders? Not a HUGE deal since the number of possible sender names is somewhat limited.
17 |
18 | ]]
19 |
20 | local CallbackHandler = LibStub("CallbackHandler-1.0")
21 | local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
22 |
23 | local MAJOR, MINOR = "AceComm-3.0", 12
24 | local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
25 |
26 | if not AceComm then return end
27 |
28 | -- Lua APIs
29 | local type, next, pairs, tostring = type, next, pairs, tostring
30 | local strsub, strfind = string.sub, string.find
31 | local match = string.match
32 | local tinsert, tconcat = table.insert, table.concat
33 | local error, assert = error, assert
34 |
35 | -- WoW APIs
36 | local Ambiguate = Ambiguate
37 |
38 | AceComm.embeds = AceComm.embeds or {}
39 |
40 | -- for my sanity and yours, let's give the message type bytes some names
41 | local MSG_MULTI_FIRST = "\001"
42 | local MSG_MULTI_NEXT = "\002"
43 | local MSG_MULTI_LAST = "\003"
44 | local MSG_ESCAPE = "\004"
45 |
46 | -- remove old structures (pre WoW 4.0)
47 | AceComm.multipart_origprefixes = nil
48 | AceComm.multipart_reassemblers = nil
49 |
50 | -- the multipart message spool: indexed by a combination of sender+distribution+
51 | AceComm.multipart_spool = AceComm.multipart_spool or {}
52 |
53 | --- Register for Addon Traffic on a specified prefix
54 | -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
55 | -- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
56 | function AceComm:RegisterComm(prefix, method)
57 | if method == nil then
58 | method = "OnCommReceived"
59 | end
60 |
61 | if #prefix > 16 then -- TODO: 15?
62 | error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
63 | end
64 | if C_ChatInfo then
65 | C_ChatInfo.RegisterAddonMessagePrefix(prefix)
66 | else
67 | RegisterAddonMessagePrefix(prefix)
68 | end
69 |
70 | return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
71 | end
72 |
73 | local warnedPrefix=false
74 |
75 | --- Send a message over the Addon Channel
76 | -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
77 | -- @param text Data to send, nils (\000) not allowed. Any length.
78 | -- @param distribution Addon channel, e.g. "RAID", "GUILD", etc; see SendAddonMessage API
79 | -- @param target Destination for some distributions; see SendAddonMessage API
80 | -- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL".
81 | -- @param callbackFn OPTIONAL: callback function to be called as each chunk is sent. receives 3 args: the user supplied arg (see next), the number of bytes sent so far, and the number of bytes total to send.
82 | -- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified.
83 | function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callbackFn, callbackArg)
84 | prio = prio or "NORMAL" -- pasta's reference implementation had different prio for singlepart and multipart, but that's a very bad idea since that can easily lead to out-of-sequence delivery!
85 | if not( type(prefix)=="string" and
86 | type(text)=="string" and
87 | type(distribution)=="string" and
88 | (target==nil or type(target)=="string" or type(target)=="number") and
89 | (prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
90 | ) then
91 | error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
92 | end
93 |
94 | local textlen = #text
95 | local maxtextlen = 255 -- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
96 | local queueName = prefix..distribution..(target or "")
97 |
98 | local ctlCallback = nil
99 | if callbackFn then
100 | ctlCallback = function(sent)
101 | return callbackFn(callbackArg, sent, textlen)
102 | end
103 | end
104 |
105 | local forceMultipart
106 | if match(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
107 | -- we need to escape the first character with a \004
108 | if textlen+1 > maxtextlen then -- would we go over the size limit?
109 | forceMultipart = true -- just make it multipart, no escape problems then
110 | else
111 | text = "\004" .. text
112 | end
113 | end
114 |
115 | if not forceMultipart and textlen <= maxtextlen then
116 | -- fits all in one message
117 | CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
118 | else
119 | maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
120 |
121 | -- first part
122 | local chunk = strsub(text, 1, maxtextlen)
123 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
124 |
125 | -- continuation
126 | local pos = 1+maxtextlen
127 |
128 | while pos+maxtextlen <= textlen do
129 | chunk = strsub(text, pos, pos+maxtextlen-1)
130 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
131 | pos = pos + maxtextlen
132 | end
133 |
134 | -- final part
135 | chunk = strsub(text, pos)
136 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
137 | end
138 | end
139 |
140 |
141 | ----------------------------------------
142 | -- Message receiving
143 | ----------------------------------------
144 |
145 | do
146 | local compost = setmetatable({}, {__mode = "k"})
147 | local function new()
148 | local t = next(compost)
149 | if t then
150 | compost[t]=nil
151 | for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
152 | t[i]=nil
153 | end
154 | return t
155 | end
156 |
157 | return {}
158 | end
159 |
160 | local function lostdatawarning(prefix,sender,where)
161 | DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
162 | end
163 |
164 | function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
165 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
166 | local spool = AceComm.multipart_spool
167 |
168 | --[[
169 | if spool[key] then
170 | lostdatawarning(prefix,sender,"First")
171 | -- continue and overwrite
172 | end
173 | --]]
174 |
175 | spool[key] = message -- plain string for now
176 | end
177 |
178 | function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender)
179 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
180 | local spool = AceComm.multipart_spool
181 | local olddata = spool[key]
182 |
183 | if not olddata then
184 | --lostdatawarning(prefix,sender,"Next")
185 | return
186 | end
187 |
188 | if type(olddata)~="table" then
189 | -- ... but what we have is not a table. So make it one. (Pull a composted one if available)
190 | local t = new()
191 | t[1] = olddata -- add old data as first string
192 | t[2] = message -- and new message as second string
193 | spool[key] = t -- and put the table in the spool instead of the old string
194 | else
195 | tinsert(olddata, message)
196 | end
197 | end
198 |
199 | function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender)
200 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
201 | local spool = AceComm.multipart_spool
202 | local olddata = spool[key]
203 |
204 | if not olddata then
205 | --lostdatawarning(prefix,sender,"End")
206 | return
207 | end
208 |
209 | spool[key] = nil
210 |
211 | if type(olddata) == "table" then
212 | -- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
213 | tinsert(olddata, message)
214 | AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender)
215 | compost[olddata] = true
216 | else
217 | -- if we've only received a "first", the spooled data will still only be a string
218 | AceComm.callbacks:Fire(prefix, olddata..message, distribution, sender)
219 | end
220 | end
221 | end
222 |
223 |
224 |
225 |
226 |
227 |
228 | ----------------------------------------
229 | -- Embed CallbackHandler
230 | ----------------------------------------
231 |
232 | if not AceComm.callbacks then
233 | AceComm.callbacks = CallbackHandler:New(AceComm,
234 | "_RegisterComm",
235 | "UnregisterComm",
236 | "UnregisterAllComm")
237 | end
238 |
239 | AceComm.callbacks.OnUsed = nil
240 | AceComm.callbacks.OnUnused = nil
241 |
242 | local function OnEvent(self, event, prefix, message, distribution, sender)
243 | if event == "CHAT_MSG_ADDON" then
244 | sender = Ambiguate(sender, "none")
245 | local control, rest = match(message, "^([\001-\009])(.*)")
246 | if control then
247 | if control==MSG_MULTI_FIRST then
248 | AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
249 | elseif control==MSG_MULTI_NEXT then
250 | AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
251 | elseif control==MSG_MULTI_LAST then
252 | AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
253 | elseif control==MSG_ESCAPE then
254 | AceComm.callbacks:Fire(prefix, rest, distribution, sender)
255 | else
256 | -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
257 | end
258 | else
259 | -- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
260 | AceComm.callbacks:Fire(prefix, message, distribution, sender)
261 | end
262 | else
263 | assert(false, "Received "..tostring(event).." event?!")
264 | end
265 | end
266 |
267 | AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame")
268 | AceComm.frame:SetScript("OnEvent", OnEvent)
269 | AceComm.frame:UnregisterAllEvents()
270 | AceComm.frame:RegisterEvent("CHAT_MSG_ADDON")
271 |
272 |
273 | ----------------------------------------
274 | -- Base library stuff
275 | ----------------------------------------
276 |
277 | local mixins = {
278 | "RegisterComm",
279 | "UnregisterComm",
280 | "UnregisterAllComm",
281 | "SendCommMessage",
282 | }
283 |
284 | -- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:..
285 | -- @param target target object to embed AceComm-3.0 in
286 | function AceComm:Embed(target)
287 | for k, v in pairs(mixins) do
288 | target[v] = self[v]
289 | end
290 | self.embeds[target] = true
291 | return target
292 | end
293 |
294 | function AceComm:OnEmbedDisable(target)
295 | target:UnregisterAllComm()
296 | end
297 |
298 | -- Update embeds
299 | for target, v in pairs(AceComm.embeds) do
300 | AceComm:Embed(target)
301 | end
302 |
--------------------------------------------------------------------------------
/Libs/AceComm-3.0/AceComm-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Libs/AceConfig-3.0/AceConfig-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceConfig-3.0 wrapper library.
2 | -- Provides an API to register an options table with the config registry,
3 | -- as well as associate it with a slash command.
4 | -- @class file
5 | -- @name AceConfig-3.0
6 | -- @release $Id: AceConfig-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
7 |
8 | --[[
9 | AceConfig-3.0
10 |
11 | Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
12 |
13 | ]]
14 |
15 | local cfgreg = LibStub("AceConfigRegistry-3.0")
16 | local cfgcmd = LibStub("AceConfigCmd-3.0")
17 |
18 | local MAJOR, MINOR = "AceConfig-3.0", 3
19 | local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
20 |
21 | if not AceConfig then return end
22 |
23 | --TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
24 | --TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
25 |
26 | -- Lua APIs
27 | local pcall, error, type, pairs = pcall, error, type, pairs
28 |
29 | -- -------------------------------------------------------------------
30 | -- :RegisterOptionsTable(appName, options, slashcmd, persist)
31 | --
32 | -- - appName - (string) application name
33 | -- - options - table or function ref, see AceConfigRegistry
34 | -- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
35 |
36 | --- Register a option table with the AceConfig registry.
37 | -- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
38 | -- @paramsig appName, options [, slashcmd]
39 | -- @param appName The application name for the config table.
40 | -- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
41 | -- @param slashcmd A slash command to register for the option table, or a table of slash commands.
42 | -- @usage
43 | -- local AceConfig = LibStub("AceConfig-3.0")
44 | -- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
45 | function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
46 | local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
47 | if not ok then error(msg, 2) end
48 |
49 | if slashcmd then
50 | if type(slashcmd) == "table" then
51 | for _,cmd in pairs(slashcmd) do
52 | cfgcmd:CreateChatCommand(cmd, appName)
53 | end
54 | else
55 | cfgcmd:CreateChatCommand(slashcmd, appName)
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/Libs/AceConfig-3.0/AceConfig-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceConsole-3.0/AceConsole-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceConsole-3.0** provides registration facilities for slash commands.
2 | -- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
3 | -- to your addons individual needs.
4 | --
5 | -- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceConsole itself.\\
8 | -- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceConsole.
10 | -- @class file
11 | -- @name AceConsole-3.0
12 | -- @release $Id: AceConsole-3.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $
13 | local MAJOR,MINOR = "AceConsole-3.0", 7
14 |
15 | local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
16 |
17 | if not AceConsole then return end -- No upgrade needed
18 |
19 | AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
20 | AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
21 | AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
22 |
23 | -- Lua APIs
24 | local tconcat, tostring, select = table.concat, tostring, select
25 | local type, pairs, error = type, pairs, error
26 | local format, strfind, strsub = string.format, string.find, string.sub
27 | local max = math.max
28 |
29 | -- WoW APIs
30 | local _G = _G
31 |
32 | local tmp={}
33 | local function Print(self,frame,...)
34 | local n=0
35 | if self ~= AceConsole then
36 | n=n+1
37 | tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
38 | end
39 | for i=1, select("#", ...) do
40 | n=n+1
41 | tmp[n] = tostring(select(i, ...))
42 | end
43 | frame:AddMessage( tconcat(tmp," ",1,n) )
44 | end
45 |
46 | --- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
47 | -- @paramsig [chatframe ,] ...
48 | -- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
49 | -- @param ... List of any values to be printed
50 | function AceConsole:Print(...)
51 | local frame = ...
52 | if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
53 | return Print(self, frame, select(2,...))
54 | else
55 | return Print(self, DEFAULT_CHAT_FRAME, ...)
56 | end
57 | end
58 |
59 |
60 | --- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
61 | -- @paramsig [chatframe ,] "format"[, ...]
62 | -- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
63 | -- @param format Format string - same syntax as standard Lua format()
64 | -- @param ... Arguments to the format string
65 | function AceConsole:Printf(...)
66 | local frame = ...
67 | if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
68 | return Print(self, frame, format(select(2,...)))
69 | else
70 | return Print(self, DEFAULT_CHAT_FRAME, format(...))
71 | end
72 | end
73 |
74 |
75 |
76 |
77 | --- Register a simple chat command
78 | -- @param command Chat command to be registered WITHOUT leading "/"
79 | -- @param func Function to call when the slash command is being used (funcref or methodname)
80 | -- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
81 | function AceConsole:RegisterChatCommand( command, func, persist )
82 | if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
83 |
84 | 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
85 |
86 | local name = "ACECONSOLE_"..command:upper()
87 |
88 | if type( func ) == "string" then
89 | SlashCmdList[name] = function(input, editBox)
90 | self[func](self, input, editBox)
91 | end
92 | else
93 | SlashCmdList[name] = func
94 | end
95 | _G["SLASH_"..name.."1"] = "/"..command:lower()
96 | AceConsole.commands[command] = name
97 | -- non-persisting commands are registered for enabling disabling
98 | if not persist then
99 | if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
100 | AceConsole.weakcommands[self][command] = func
101 | end
102 | return true
103 | end
104 |
105 | --- Unregister a chatcommand
106 | -- @param command Chat command to be unregistered WITHOUT leading "/"
107 | function AceConsole:UnregisterChatCommand( command )
108 | local name = AceConsole.commands[command]
109 | if name then
110 | SlashCmdList[name] = nil
111 | _G["SLASH_" .. name .. "1"] = nil
112 | hash_SlashCmdList["/" .. command:upper()] = nil
113 | AceConsole.commands[command] = nil
114 | end
115 | end
116 |
117 | --- Get an iterator over all Chat Commands registered with AceConsole
118 | -- @return Iterator (pairs) over all commands
119 | function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
120 |
121 |
122 | local function nils(n, ...)
123 | if n>1 then
124 | return nil, nils(n-1, ...)
125 | elseif n==1 then
126 | return nil, ...
127 | else
128 | return ...
129 | end
130 | end
131 |
132 |
133 | --- Retreive one or more space-separated arguments from a string.
134 | -- Treats quoted strings and itemlinks as non-spaced.
135 | -- @param str The raw argument string
136 | -- @param numargs How many arguments to get (default 1)
137 | -- @param startpos Where in the string to start scanning (default 1)
138 | -- @return Returns arg1, arg2, ..., nextposition\\
139 | -- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
140 | function AceConsole:GetArgs(str, numargs, startpos)
141 | numargs = numargs or 1
142 | startpos = max(startpos or 1, 1)
143 |
144 | local pos=startpos
145 |
146 | -- find start of new arg
147 | pos = strfind(str, "[^ ]", pos)
148 | if not pos then -- whoops, end of string
149 | return nils(numargs, 1e9)
150 | end
151 |
152 | if numargs<1 then
153 | return pos
154 | end
155 |
156 | -- quoted or space separated? find out which pattern to use
157 | local delim_or_pipe
158 | local ch = strsub(str, pos, pos)
159 | if ch=='"' then
160 | pos = pos + 1
161 | delim_or_pipe='([|"])'
162 | elseif ch=="'" then
163 | pos = pos + 1
164 | delim_or_pipe="([|'])"
165 | else
166 | delim_or_pipe="([| ])"
167 | end
168 |
169 | startpos = pos
170 |
171 | while true do
172 | -- find delimiter or hyperlink
173 | local _
174 | pos,_,ch = strfind(str, delim_or_pipe, pos)
175 |
176 | if not pos then break end
177 |
178 | if ch=="|" then
179 | -- some kind of escape
180 |
181 | if strsub(str,pos,pos+1)=="|H" then
182 | -- It's a |H....|hhyper link!|h
183 | pos=strfind(str, "|h", pos+2) -- first |h
184 | if not pos then break end
185 |
186 | pos=strfind(str, "|h", pos+2) -- second |h
187 | if not pos then break end
188 | elseif strsub(str,pos, pos+1) == "|T" then
189 | -- It's a |T....|t texture
190 | pos=strfind(str, "|t", pos+2)
191 | if not pos then break end
192 | end
193 |
194 | pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
195 |
196 | else
197 | -- found delimiter, done with this arg
198 | return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
199 | end
200 |
201 | end
202 |
203 | -- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
204 | return strsub(str, startpos), nils(numargs-1, 1e9)
205 | end
206 |
207 |
208 | --- embedding and embed handling
209 |
210 | local mixins = {
211 | "Print",
212 | "Printf",
213 | "RegisterChatCommand",
214 | "UnregisterChatCommand",
215 | "GetArgs",
216 | }
217 |
218 | -- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
219 | -- @param target target object to embed AceBucket in
220 | function AceConsole:Embed( target )
221 | for k, v in pairs( mixins ) do
222 | target[v] = self[v]
223 | end
224 | self.embeds[target] = true
225 | return target
226 | end
227 |
228 | function AceConsole:OnEmbedEnable( target )
229 | if AceConsole.weakcommands[target] then
230 | for command, func in pairs( AceConsole.weakcommands[target] ) do
231 | target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
232 | end
233 | end
234 | end
235 |
236 | function AceConsole:OnEmbedDisable( target )
237 | if AceConsole.weakcommands[target] then
238 | for command, func in pairs( AceConsole.weakcommands[target] ) do
239 | target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
240 | end
241 | end
242 | end
243 |
244 | for addon in pairs(AceConsole.embeds) do
245 | AceConsole:Embed(addon)
246 | end
247 |
--------------------------------------------------------------------------------
/Libs/AceConsole-3.0/AceConsole-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceDB-3.0/AceDB-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceEvent-3.0/AceEvent-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceEvent-3.0 provides event registration and secure dispatching.
2 | -- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
3 | -- CallbackHandler, and dispatches all game events or addon message to the registrees.
4 | --
5 | -- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceEvent itself.\\
8 | -- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceEvent.
10 | -- @class file
11 | -- @name AceEvent-3.0
12 | -- @release $Id: AceEvent-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
13 | local CallbackHandler = LibStub("CallbackHandler-1.0")
14 |
15 | local MAJOR, MINOR = "AceEvent-3.0", 4
16 | local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
17 |
18 | if not AceEvent then return end
19 |
20 | -- Lua APIs
21 | local pairs = pairs
22 |
23 | AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
24 | AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
25 |
26 | -- APIs and registry for blizzard events, using CallbackHandler lib
27 | if not AceEvent.events then
28 | AceEvent.events = CallbackHandler:New(AceEvent,
29 | "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
30 | end
31 |
32 | function AceEvent.events:OnUsed(target, eventname)
33 | AceEvent.frame:RegisterEvent(eventname)
34 | end
35 |
36 | function AceEvent.events:OnUnused(target, eventname)
37 | AceEvent.frame:UnregisterEvent(eventname)
38 | end
39 |
40 |
41 | -- APIs and registry for IPC messages, using CallbackHandler lib
42 | if not AceEvent.messages then
43 | AceEvent.messages = CallbackHandler:New(AceEvent,
44 | "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
45 | )
46 | AceEvent.SendMessage = AceEvent.messages.Fire
47 | end
48 |
49 | --- embedding and embed handling
50 | local mixins = {
51 | "RegisterEvent", "UnregisterEvent",
52 | "RegisterMessage", "UnregisterMessage",
53 | "SendMessage",
54 | "UnregisterAllEvents", "UnregisterAllMessages",
55 | }
56 |
57 | --- Register for a Blizzard Event.
58 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
59 | -- Any arguments to the event will be passed on after that.
60 | -- @name AceEvent:RegisterEvent
61 | -- @class function
62 | -- @paramsig event[, callback [, arg]]
63 | -- @param event The event to register for
64 | -- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
65 | -- @param arg An optional argument to pass to the callback function
66 |
67 | --- Unregister an event.
68 | -- @name AceEvent:UnregisterEvent
69 | -- @class function
70 | -- @paramsig event
71 | -- @param event The event to unregister
72 |
73 | --- Register for a custom AceEvent-internal message.
74 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
75 | -- Any arguments to the event will be passed on after that.
76 | -- @name AceEvent:RegisterMessage
77 | -- @class function
78 | -- @paramsig message[, callback [, arg]]
79 | -- @param message The message to register for
80 | -- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
81 | -- @param arg An optional argument to pass to the callback function
82 |
83 | --- Unregister a message
84 | -- @name AceEvent:UnregisterMessage
85 | -- @class function
86 | -- @paramsig message
87 | -- @param message The message to unregister
88 |
89 | --- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
90 | -- @name AceEvent:SendMessage
91 | -- @class function
92 | -- @paramsig message, ...
93 | -- @param message The message to send
94 | -- @param ... Any arguments to the message
95 |
96 |
97 | -- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
98 | -- @param target target object to embed AceEvent in
99 | function AceEvent:Embed(target)
100 | for k, v in pairs(mixins) do
101 | target[v] = self[v]
102 | end
103 | self.embeds[target] = true
104 | return target
105 | end
106 |
107 | -- AceEvent:OnEmbedDisable( target )
108 | -- target (object) - target object that is being disabled
109 | --
110 | -- Unregister all events messages etc when the target disables.
111 | -- this method should be called by the target manually or by an addon framework
112 | function AceEvent:OnEmbedDisable(target)
113 | target:UnregisterAllEvents()
114 | target:UnregisterAllMessages()
115 | end
116 |
117 | -- Script to fire blizzard events into the event listeners
118 | local events = AceEvent.events
119 | AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
120 | events:Fire(event, ...)
121 | end)
122 |
123 | --- Finally: upgrade our old embeds
124 | for target, v in pairs(AceEvent.embeds) do
125 | AceEvent:Embed(target)
126 | end
127 |
--------------------------------------------------------------------------------
/Libs/AceEvent-3.0/AceEvent-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/AceGUI-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | BlizOptionsGroup Container
3 | Simple container widget for the integration of AceGUI into the Blizzard Interface Options
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "BlizOptionsGroup", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 |
19 | local function OnShow(frame)
20 | frame.obj:Fire("OnShow")
21 | end
22 |
23 | local function OnHide(frame)
24 | frame.obj:Fire("OnHide")
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Support functions
29 | -------------------------------------------------------------------------------]]
30 |
31 | local function okay(frame)
32 | frame.obj:Fire("okay")
33 | end
34 |
35 | local function cancel(frame)
36 | frame.obj:Fire("cancel")
37 | end
38 |
39 | local function default(frame)
40 | frame.obj:Fire("default")
41 | end
42 |
43 | local function refresh(frame)
44 | frame.obj:Fire("refresh")
45 | end
46 |
47 | --[[-----------------------------------------------------------------------------
48 | Methods
49 | -------------------------------------------------------------------------------]]
50 |
51 | local methods = {
52 | ["OnAcquire"] = function(self)
53 | self:SetName()
54 | self:SetTitle()
55 | end,
56 |
57 | -- ["OnRelease"] = nil,
58 |
59 | ["OnWidthSet"] = function(self, width)
60 | local content = self.content
61 | local contentwidth = width - 63
62 | if contentwidth < 0 then
63 | contentwidth = 0
64 | end
65 | content:SetWidth(contentwidth)
66 | content.width = contentwidth
67 | end,
68 |
69 | ["OnHeightSet"] = function(self, height)
70 | local content = self.content
71 | local contentheight = height - 26
72 | if contentheight < 0 then
73 | contentheight = 0
74 | end
75 | content:SetHeight(contentheight)
76 | content.height = contentheight
77 | end,
78 |
79 | ["SetName"] = function(self, name, parent)
80 | self.frame.name = name
81 | self.frame.parent = parent
82 | end,
83 |
84 | ["SetTitle"] = function(self, title)
85 | local content = self.content
86 | content:ClearAllPoints()
87 | if not title or title == "" then
88 | content:SetPoint("TOPLEFT", 10, -10)
89 | self.label:SetText("")
90 | else
91 | content:SetPoint("TOPLEFT", 10, -40)
92 | self.label:SetText(title)
93 | end
94 | content:SetPoint("BOTTOMRIGHT", -10, 10)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local function Constructor()
102 | local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
103 | frame:Hide()
104 |
105 | -- support functions for the Blizzard Interface Options
106 | frame.okay = okay
107 | frame.cancel = cancel
108 | frame.default = default
109 | frame.refresh = refresh
110 |
111 | -- 10.0 support function aliases (cancel has been removed)
112 | frame.OnCommit = okay
113 | frame.OnDefault = default
114 | frame.OnRefresh = refresh
115 |
116 | frame:SetScript("OnHide", OnHide)
117 | frame:SetScript("OnShow", OnShow)
118 |
119 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
120 | label:SetPoint("TOPLEFT", 10, -15)
121 | label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
122 | label:SetJustifyH("LEFT")
123 | label:SetJustifyV("TOP")
124 |
125 | --Container Support
126 | local content = CreateFrame("Frame", nil, frame)
127 | content:SetPoint("TOPLEFT", 10, -10)
128 | content:SetPoint("BOTTOMRIGHT", -10, 10)
129 |
130 | local widget = {
131 | label = label,
132 | frame = frame,
133 | content = content,
134 | type = Type
135 | }
136 | for method, func in pairs(methods) do
137 | widget[method] = func
138 | end
139 |
140 | return AceGUI:RegisterAsContainer(widget)
141 | end
142 |
143 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
144 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | DropdownGroup Container
3 | Container controlled by a dropdown on the top.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "DropdownGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local assert, pairs, type = assert, pairs, type
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 | local function SelectedGroup(self, event, value)
19 | local group = self.parentgroup
20 | local status = group.status or group.localstatus
21 | status.selected = value
22 | self.parentgroup:Fire("OnGroupSelected", value)
23 | end
24 |
25 | --[[-----------------------------------------------------------------------------
26 | Methods
27 | -------------------------------------------------------------------------------]]
28 | local methods = {
29 | ["OnAcquire"] = function(self)
30 | self.dropdown:SetText("")
31 | self:SetDropdownWidth(200)
32 | self:SetTitle("")
33 | end,
34 |
35 | ["OnRelease"] = function(self)
36 | self.dropdown.list = nil
37 | self.status = nil
38 | for k in pairs(self.localstatus) do
39 | self.localstatus[k] = nil
40 | end
41 | end,
42 |
43 | ["SetTitle"] = function(self, title)
44 | self.titletext:SetText(title)
45 | self.dropdown.frame:ClearAllPoints()
46 | if title and title ~= "" then
47 | self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
48 | else
49 | self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
50 | end
51 | end,
52 |
53 | ["SetGroupList"] = function(self,list,order)
54 | self.dropdown:SetList(list,order)
55 | end,
56 |
57 | ["SetStatusTable"] = function(self, status)
58 | assert(type(status) == "table")
59 | self.status = status
60 | end,
61 |
62 | ["SetGroup"] = function(self,group)
63 | self.dropdown:SetValue(group)
64 | local status = self.status or self.localstatus
65 | status.selected = group
66 | self:Fire("OnGroupSelected", group)
67 | end,
68 |
69 | ["OnWidthSet"] = function(self, width)
70 | local content = self.content
71 | local contentwidth = width - 26
72 | if contentwidth < 0 then
73 | contentwidth = 0
74 | end
75 | content:SetWidth(contentwidth)
76 | content.width = contentwidth
77 | end,
78 |
79 | ["OnHeightSet"] = function(self, height)
80 | local content = self.content
81 | local contentheight = height - 63
82 | if contentheight < 0 then
83 | contentheight = 0
84 | end
85 | content:SetHeight(contentheight)
86 | content.height = contentheight
87 | end,
88 |
89 | ["LayoutFinished"] = function(self, width, height)
90 | self:SetHeight((height or 0) + 63)
91 | end,
92 |
93 | ["SetDropdownWidth"] = function(self, width)
94 | self.dropdown:SetWidth(width)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local PaneBackdrop = {
102 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
103 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
104 | tile = true, tileSize = 16, edgeSize = 16,
105 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
106 | }
107 |
108 | local function Constructor()
109 | local frame = CreateFrame("Frame")
110 | frame:SetHeight(100)
111 | frame:SetWidth(100)
112 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
113 |
114 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
115 | titletext:SetPoint("TOPLEFT", 4, -5)
116 | titletext:SetPoint("TOPRIGHT", -4, -5)
117 | titletext:SetJustifyH("LEFT")
118 | titletext:SetHeight(18)
119 |
120 | local dropdown = AceGUI:Create("Dropdown")
121 | dropdown.frame:SetParent(frame)
122 | dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
123 | dropdown:SetCallback("OnValueChanged", SelectedGroup)
124 | dropdown.frame:SetPoint("TOPLEFT", -1, 0)
125 | dropdown.frame:Show()
126 | dropdown:SetLabel("")
127 |
128 | local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
129 | border:SetPoint("TOPLEFT", 0, -26)
130 | border:SetPoint("BOTTOMRIGHT", 0, 3)
131 | border:SetBackdrop(PaneBackdrop)
132 | border:SetBackdropColor(0.1,0.1,0.1,0.5)
133 | border:SetBackdropBorderColor(0.4,0.4,0.4)
134 |
135 | --Container Support
136 | local content = CreateFrame("Frame", nil, border)
137 | content:SetPoint("TOPLEFT", 10, -10)
138 | content:SetPoint("BOTTOMRIGHT", -10, 10)
139 |
140 | local widget = {
141 | frame = frame,
142 | localstatus = {},
143 | titletext = titletext,
144 | dropdown = dropdown,
145 | border = border,
146 | content = content,
147 | type = Type
148 | }
149 | for method, func in pairs(methods) do
150 | widget[method] = func
151 | end
152 | dropdown.parentgroup = widget
153 |
154 | return AceGUI:RegisterAsContainer(widget)
155 | end
156 |
157 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
158 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Frame Container
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Frame", 30
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs, assert, type = pairs, assert, type
10 | local wipe = table.wipe
11 |
12 | -- WoW APIs
13 | local PlaySound = PlaySound
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 | local function Button_OnClick(frame)
20 | PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
21 | frame.obj:Hide()
22 | end
23 |
24 | local function Frame_OnShow(frame)
25 | frame.obj:Fire("OnShow")
26 | end
27 |
28 | local function Frame_OnClose(frame)
29 | frame.obj:Fire("OnClose")
30 | end
31 |
32 | local function Frame_OnMouseDown(frame)
33 | AceGUI:ClearFocus()
34 | end
35 |
36 | local function Title_OnMouseDown(frame)
37 | frame:GetParent():StartMoving()
38 | AceGUI:ClearFocus()
39 | end
40 |
41 | local function MoverSizer_OnMouseUp(mover)
42 | local frame = mover:GetParent()
43 | frame:StopMovingOrSizing()
44 | local self = frame.obj
45 | local status = self.status or self.localstatus
46 | status.width = frame:GetWidth()
47 | status.height = frame:GetHeight()
48 | status.top = frame:GetTop()
49 | status.left = frame:GetLeft()
50 | end
51 |
52 | local function SizerSE_OnMouseDown(frame)
53 | frame:GetParent():StartSizing("BOTTOMRIGHT")
54 | AceGUI:ClearFocus()
55 | end
56 |
57 | local function SizerS_OnMouseDown(frame)
58 | frame:GetParent():StartSizing("BOTTOM")
59 | AceGUI:ClearFocus()
60 | end
61 |
62 | local function SizerE_OnMouseDown(frame)
63 | frame:GetParent():StartSizing("RIGHT")
64 | AceGUI:ClearFocus()
65 | end
66 |
67 | local function StatusBar_OnEnter(frame)
68 | frame.obj:Fire("OnEnterStatusBar")
69 | end
70 |
71 | local function StatusBar_OnLeave(frame)
72 | frame.obj:Fire("OnLeaveStatusBar")
73 | end
74 |
75 | --[[-----------------------------------------------------------------------------
76 | Methods
77 | -------------------------------------------------------------------------------]]
78 | local methods = {
79 | ["OnAcquire"] = function(self)
80 | self.frame:SetParent(UIParent)
81 | self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
82 | self.frame:SetFrameLevel(100) -- Lots of room to draw under it
83 | self:SetTitle()
84 | self:SetStatusText()
85 | self:ApplyStatus()
86 | self:Show()
87 | self:EnableResize(true)
88 | end,
89 |
90 | ["OnRelease"] = function(self)
91 | self.status = nil
92 | wipe(self.localstatus)
93 | end,
94 |
95 | ["OnWidthSet"] = function(self, width)
96 | local content = self.content
97 | local contentwidth = width - 34
98 | if contentwidth < 0 then
99 | contentwidth = 0
100 | end
101 | content:SetWidth(contentwidth)
102 | content.width = contentwidth
103 | end,
104 |
105 | ["OnHeightSet"] = function(self, height)
106 | local content = self.content
107 | local contentheight = height - 57
108 | if contentheight < 0 then
109 | contentheight = 0
110 | end
111 | content:SetHeight(contentheight)
112 | content.height = contentheight
113 | end,
114 |
115 | ["SetTitle"] = function(self, title)
116 | self.titletext:SetText(title)
117 | self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
118 | end,
119 |
120 | ["SetStatusText"] = function(self, text)
121 | self.statustext:SetText(text)
122 | end,
123 |
124 | ["Hide"] = function(self)
125 | self.frame:Hide()
126 | end,
127 |
128 | ["Show"] = function(self)
129 | self.frame:Show()
130 | end,
131 |
132 | ["EnableResize"] = function(self, state)
133 | local func = state and "Show" or "Hide"
134 | self.sizer_se[func](self.sizer_se)
135 | self.sizer_s[func](self.sizer_s)
136 | self.sizer_e[func](self.sizer_e)
137 | end,
138 |
139 | -- called to set an external table to store status in
140 | ["SetStatusTable"] = function(self, status)
141 | assert(type(status) == "table")
142 | self.status = status
143 | self:ApplyStatus()
144 | end,
145 |
146 | ["ApplyStatus"] = function(self)
147 | local status = self.status or self.localstatus
148 | local frame = self.frame
149 | self:SetWidth(status.width or 700)
150 | self:SetHeight(status.height or 500)
151 | frame:ClearAllPoints()
152 | if status.top and status.left then
153 | frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
154 | frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
155 | else
156 | frame:SetPoint("CENTER")
157 | end
158 | end
159 | }
160 |
161 | --[[-----------------------------------------------------------------------------
162 | Constructor
163 | -------------------------------------------------------------------------------]]
164 | local FrameBackdrop = {
165 | bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
166 | edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
167 | tile = true, tileSize = 32, edgeSize = 32,
168 | insets = { left = 8, right = 8, top = 8, bottom = 8 }
169 | }
170 |
171 | local PaneBackdrop = {
172 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
173 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
174 | tile = true, tileSize = 16, edgeSize = 16,
175 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
176 | }
177 |
178 | local function Constructor()
179 | local frame = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
180 | frame:Hide()
181 |
182 | frame:EnableMouse(true)
183 | frame:SetMovable(true)
184 | frame:SetResizable(true)
185 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
186 | frame:SetFrameLevel(100) -- Lots of room to draw under it
187 | frame:SetBackdrop(FrameBackdrop)
188 | frame:SetBackdropColor(0, 0, 0, 1)
189 | if frame.SetResizeBounds then -- WoW 10.0
190 | frame:SetResizeBounds(400, 200)
191 | else
192 | frame:SetMinResize(400, 200)
193 | end
194 | frame:SetToplevel(true)
195 | frame:SetScript("OnShow", Frame_OnShow)
196 | frame:SetScript("OnHide", Frame_OnClose)
197 | frame:SetScript("OnMouseDown", Frame_OnMouseDown)
198 |
199 | local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
200 | closebutton:SetScript("OnClick", Button_OnClick)
201 | closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
202 | closebutton:SetHeight(20)
203 | closebutton:SetWidth(100)
204 | closebutton:SetText(CLOSE)
205 |
206 | local statusbg = CreateFrame("Button", nil, frame, "BackdropTemplate")
207 | statusbg:SetPoint("BOTTOMLEFT", 15, 15)
208 | statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
209 | statusbg:SetHeight(24)
210 | statusbg:SetBackdrop(PaneBackdrop)
211 | statusbg:SetBackdropColor(0.1,0.1,0.1)
212 | statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
213 | statusbg:SetScript("OnEnter", StatusBar_OnEnter)
214 | statusbg:SetScript("OnLeave", StatusBar_OnLeave)
215 |
216 | local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
217 | statustext:SetPoint("TOPLEFT", 7, -2)
218 | statustext:SetPoint("BOTTOMRIGHT", -7, 2)
219 | statustext:SetHeight(20)
220 | statustext:SetJustifyH("LEFT")
221 | statustext:SetText("")
222 |
223 | local titlebg = frame:CreateTexture(nil, "OVERLAY")
224 | titlebg:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
225 | titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
226 | titlebg:SetPoint("TOP", 0, 12)
227 | titlebg:SetWidth(100)
228 | titlebg:SetHeight(40)
229 |
230 | local title = CreateFrame("Frame", nil, frame)
231 | title:EnableMouse(true)
232 | title:SetScript("OnMouseDown", Title_OnMouseDown)
233 | title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
234 | title:SetAllPoints(titlebg)
235 |
236 | local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
237 | titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
238 |
239 | local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
240 | titlebg_l:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
241 | titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
242 | titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
243 | titlebg_l:SetWidth(30)
244 | titlebg_l:SetHeight(40)
245 |
246 | local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
247 | titlebg_r:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
248 | titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
249 | titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
250 | titlebg_r:SetWidth(30)
251 | titlebg_r:SetHeight(40)
252 |
253 | local sizer_se = CreateFrame("Frame", nil, frame)
254 | sizer_se:SetPoint("BOTTOMRIGHT")
255 | sizer_se:SetWidth(25)
256 | sizer_se:SetHeight(25)
257 | sizer_se:EnableMouse()
258 | sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
259 | sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
260 |
261 | local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
262 | line1:SetWidth(14)
263 | line1:SetHeight(14)
264 | line1:SetPoint("BOTTOMRIGHT", -8, 8)
265 | line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
266 | local x = 0.1 * 14/17
267 | line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
268 |
269 | local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
270 | line2:SetWidth(8)
271 | line2:SetHeight(8)
272 | line2:SetPoint("BOTTOMRIGHT", -8, 8)
273 | line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
274 | x = 0.1 * 8/17
275 | line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
276 |
277 | local sizer_s = CreateFrame("Frame", nil, frame)
278 | sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
279 | sizer_s:SetPoint("BOTTOMLEFT")
280 | sizer_s:SetHeight(25)
281 | sizer_s:EnableMouse(true)
282 | sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
283 | sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
284 |
285 | local sizer_e = CreateFrame("Frame", nil, frame)
286 | sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
287 | sizer_e:SetPoint("TOPRIGHT")
288 | sizer_e:SetWidth(25)
289 | sizer_e:EnableMouse(true)
290 | sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
291 | sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
292 |
293 | --Container Support
294 | local content = CreateFrame("Frame", nil, frame)
295 | content:SetPoint("TOPLEFT", 17, -27)
296 | content:SetPoint("BOTTOMRIGHT", -17, 40)
297 |
298 | local widget = {
299 | localstatus = {},
300 | titletext = titletext,
301 | statustext = statustext,
302 | titlebg = titlebg,
303 | sizer_se = sizer_se,
304 | sizer_s = sizer_s,
305 | sizer_e = sizer_e,
306 | content = content,
307 | frame = frame,
308 | type = Type
309 | }
310 | for method, func in pairs(methods) do
311 | widget[method] = func
312 | end
313 | closebutton.obj, statusbg.obj = widget, widget
314 |
315 | return AceGUI:RegisterAsContainer(widget)
316 | end
317 |
318 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
319 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InlineGroup Container
3 | Simple container widget that creates a visible "box" with an optional title.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "InlineGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Methods
17 | -------------------------------------------------------------------------------]]
18 | local methods = {
19 | ["OnAcquire"] = function(self)
20 | self:SetWidth(300)
21 | self:SetHeight(100)
22 | self:SetTitle("")
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["SetTitle"] = function(self,title)
28 | self.titletext:SetText(title)
29 | end,
30 |
31 |
32 | ["LayoutFinished"] = function(self, width, height)
33 | if self.noAutoHeight then return end
34 | self:SetHeight((height or 0) + 40)
35 | end,
36 |
37 | ["OnWidthSet"] = function(self, width)
38 | local content = self.content
39 | local contentwidth = width - 20
40 | if contentwidth < 0 then
41 | contentwidth = 0
42 | end
43 | content:SetWidth(contentwidth)
44 | content.width = contentwidth
45 | end,
46 |
47 | ["OnHeightSet"] = function(self, height)
48 | local content = self.content
49 | local contentheight = height - 20
50 | if contentheight < 0 then
51 | contentheight = 0
52 | end
53 | content:SetHeight(contentheight)
54 | content.height = contentheight
55 | end
56 | }
57 |
58 | --[[-----------------------------------------------------------------------------
59 | Constructor
60 | -------------------------------------------------------------------------------]]
61 | local PaneBackdrop = {
62 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
63 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
64 | tile = true, tileSize = 16, edgeSize = 16,
65 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
66 | }
67 |
68 | local function Constructor()
69 | local frame = CreateFrame("Frame", nil, UIParent)
70 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
71 |
72 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
73 | titletext:SetPoint("TOPLEFT", 14, 0)
74 | titletext:SetPoint("TOPRIGHT", -14, 0)
75 | titletext:SetJustifyH("LEFT")
76 | titletext:SetHeight(18)
77 |
78 | local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
79 | border:SetPoint("TOPLEFT", 0, -17)
80 | border:SetPoint("BOTTOMRIGHT", -1, 3)
81 | border:SetBackdrop(PaneBackdrop)
82 | border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
83 | border:SetBackdropBorderColor(0.4, 0.4, 0.4)
84 |
85 | --Container Support
86 | local content = CreateFrame("Frame", nil, border)
87 | content:SetPoint("TOPLEFT", 10, -10)
88 | content:SetPoint("BOTTOMRIGHT", -10, 10)
89 |
90 | local widget = {
91 | frame = frame,
92 | content = content,
93 | titletext = titletext,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsContainer(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ScrollFrame Container
3 | Plain container that scrolls its content and doesn't grow in height.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "ScrollFrame", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs, assert, type = pairs, assert, type
11 | local min, max, floor = math.min, math.max, math.floor
12 |
13 | -- WoW APIs
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Support functions
18 | -------------------------------------------------------------------------------]]
19 | local function FixScrollOnUpdate(frame)
20 | frame:SetScript("OnUpdate", nil)
21 | frame.obj:FixScroll()
22 | end
23 |
24 | --[[-----------------------------------------------------------------------------
25 | Scripts
26 | -------------------------------------------------------------------------------]]
27 | local function ScrollFrame_OnMouseWheel(frame, value)
28 | frame.obj:MoveScroll(value)
29 | end
30 |
31 | local function ScrollFrame_OnSizeChanged(frame)
32 | frame:SetScript("OnUpdate", FixScrollOnUpdate)
33 | end
34 |
35 | local function ScrollBar_OnScrollValueChanged(frame, value)
36 | frame.obj:SetScroll(value)
37 | end
38 |
39 | --[[-----------------------------------------------------------------------------
40 | Methods
41 | -------------------------------------------------------------------------------]]
42 | local methods = {
43 | ["OnAcquire"] = function(self)
44 | self:SetScroll(0)
45 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
46 | end,
47 |
48 | ["OnRelease"] = function(self)
49 | self.status = nil
50 | for k in pairs(self.localstatus) do
51 | self.localstatus[k] = nil
52 | end
53 | self.scrollframe:SetPoint("BOTTOMRIGHT")
54 | self.scrollbar:Hide()
55 | self.scrollBarShown = nil
56 | self.content.height, self.content.width, self.content.original_width = nil, nil, nil
57 | end,
58 |
59 | ["SetScroll"] = function(self, value)
60 | local status = self.status or self.localstatus
61 | local viewheight = self.scrollframe:GetHeight()
62 | local height = self.content:GetHeight()
63 | local offset
64 |
65 | if viewheight > height then
66 | offset = 0
67 | else
68 | offset = floor((height - viewheight) / 1000.0 * value)
69 | end
70 | self.content:ClearAllPoints()
71 | self.content:SetPoint("TOPLEFT", 0, offset)
72 | self.content:SetPoint("TOPRIGHT", 0, offset)
73 | status.offset = offset
74 | status.scrollvalue = value
75 | end,
76 |
77 | ["MoveScroll"] = function(self, value)
78 | local status = self.status or self.localstatus
79 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
80 |
81 | if self.scrollBarShown then
82 | local diff = height - viewheight
83 | local delta = 1
84 | if value < 0 then
85 | delta = -1
86 | end
87 | self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
88 | end
89 | end,
90 |
91 | ["FixScroll"] = function(self)
92 | if self.updateLock then return end
93 | self.updateLock = true
94 | local status = self.status or self.localstatus
95 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
96 | local offset = status.offset or 0
97 | -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
98 | -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
99 | if viewheight < height + 2 then
100 | if self.scrollBarShown then
101 | self.scrollBarShown = nil
102 | self.scrollbar:Hide()
103 | self.scrollbar:SetValue(0)
104 | self.scrollframe:SetPoint("BOTTOMRIGHT")
105 | if self.content.original_width then
106 | self.content.width = self.content.original_width
107 | end
108 | self:DoLayout()
109 | end
110 | else
111 | if not self.scrollBarShown then
112 | self.scrollBarShown = true
113 | self.scrollbar:Show()
114 | self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
115 | if self.content.original_width then
116 | self.content.width = self.content.original_width - 20
117 | end
118 | self:DoLayout()
119 | end
120 | local value = (offset / (viewheight - height) * 1000)
121 | if value > 1000 then value = 1000 end
122 | self.scrollbar:SetValue(value)
123 | self:SetScroll(value)
124 | if value < 1000 then
125 | self.content:ClearAllPoints()
126 | self.content:SetPoint("TOPLEFT", 0, offset)
127 | self.content:SetPoint("TOPRIGHT", 0, offset)
128 | status.offset = offset
129 | end
130 | end
131 | self.updateLock = nil
132 | end,
133 |
134 | ["LayoutFinished"] = function(self, width, height)
135 | self.content:SetHeight(height or 0 + 20)
136 |
137 | -- update the scrollframe
138 | self:FixScroll()
139 |
140 | -- schedule another update when everything has "settled"
141 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
142 | end,
143 |
144 | ["SetStatusTable"] = function(self, status)
145 | assert(type(status) == "table")
146 | self.status = status
147 | if not status.scrollvalue then
148 | status.scrollvalue = 0
149 | end
150 | end,
151 |
152 | ["OnWidthSet"] = function(self, width)
153 | local content = self.content
154 | content.width = width - (self.scrollBarShown and 20 or 0)
155 | content.original_width = width
156 | end,
157 |
158 | ["OnHeightSet"] = function(self, height)
159 | local content = self.content
160 | content.height = height
161 | end
162 | }
163 | --[[-----------------------------------------------------------------------------
164 | Constructor
165 | -------------------------------------------------------------------------------]]
166 | local function Constructor()
167 | local frame = CreateFrame("Frame", nil, UIParent)
168 | local num = AceGUI:GetNextWidgetNum(Type)
169 |
170 | local scrollframe = CreateFrame("ScrollFrame", nil, frame)
171 | scrollframe:SetPoint("TOPLEFT")
172 | scrollframe:SetPoint("BOTTOMRIGHT")
173 | scrollframe:EnableMouseWheel(true)
174 | scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
175 | scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
176 |
177 | local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
178 | scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
179 | scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
180 | scrollbar:SetMinMaxValues(0, 1000)
181 | scrollbar:SetValueStep(1)
182 | scrollbar:SetValue(0)
183 | scrollbar:SetWidth(16)
184 | scrollbar:Hide()
185 | -- set the script as the last step, so it doesn't fire yet
186 | scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
187 |
188 | local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
189 | scrollbg:SetAllPoints(scrollbar)
190 | scrollbg:SetColorTexture(0, 0, 0, 0.4)
191 |
192 | --Container Support
193 | local content = CreateFrame("Frame", nil, scrollframe)
194 | content:SetPoint("TOPLEFT")
195 | content:SetPoint("TOPRIGHT")
196 | content:SetHeight(400)
197 | scrollframe:SetScrollChild(content)
198 |
199 | local widget = {
200 | localstatus = { scrollvalue = 0 },
201 | scrollframe = scrollframe,
202 | scrollbar = scrollbar,
203 | content = content,
204 | frame = frame,
205 | type = Type
206 | }
207 | for method, func in pairs(methods) do
208 | widget[method] = func
209 | end
210 | scrollframe.obj, scrollbar.obj = widget, widget
211 |
212 | return AceGUI:RegisterAsContainer(widget)
213 | end
214 |
215 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
216 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | SimpleGroup Container
3 | Simple container widget that just groups widgets.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "SimpleGroup", 20
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Methods
18 | -------------------------------------------------------------------------------]]
19 | local methods = {
20 | ["OnAcquire"] = function(self)
21 | self:SetWidth(300)
22 | self:SetHeight(100)
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["LayoutFinished"] = function(self, width, height)
28 | if self.noAutoHeight then return end
29 | self:SetHeight(height or 0)
30 | end,
31 |
32 | ["OnWidthSet"] = function(self, width)
33 | local content = self.content
34 | content:SetWidth(width)
35 | content.width = width
36 | end,
37 |
38 | ["OnHeightSet"] = function(self, height)
39 | local content = self.content
40 | content:SetHeight(height)
41 | content.height = height
42 | end
43 | }
44 |
45 | --[[-----------------------------------------------------------------------------
46 | Constructor
47 | -------------------------------------------------------------------------------]]
48 | local function Constructor()
49 | local frame = CreateFrame("Frame", nil, UIParent)
50 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
51 |
52 | --Container Support
53 | local content = CreateFrame("Frame", nil, frame)
54 | content:SetPoint("TOPLEFT")
55 | content:SetPoint("BOTTOMRIGHT")
56 |
57 | local widget = {
58 | frame = frame,
59 | content = content,
60 | type = Type
61 | }
62 | for method, func in pairs(methods) do
63 | widget[method] = func
64 | end
65 |
66 | return AceGUI:RegisterAsContainer(widget)
67 | end
68 |
69 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
70 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua:
--------------------------------------------------------------------------------
1 | local AceGUI = LibStub("AceGUI-3.0")
2 |
3 | -- Lua APIs
4 | local pairs, assert, type = pairs, assert, type
5 |
6 | -- WoW APIs
7 | local PlaySound = PlaySound
8 | local CreateFrame, UIParent = CreateFrame, UIParent
9 |
10 | ----------------
11 | -- Main Frame --
12 | ----------------
13 | --[[
14 | Events :
15 | OnClose
16 |
17 | ]]
18 | do
19 | local Type = "Window"
20 | local Version = 8
21 |
22 | local function frameOnShow(this)
23 | this.obj:Fire("OnShow")
24 | end
25 |
26 | local function frameOnClose(this)
27 | this.obj:Fire("OnClose")
28 | end
29 |
30 | local function closeOnClick(this)
31 | PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
32 | this.obj:Hide()
33 | end
34 |
35 | local function frameOnMouseDown(this)
36 | AceGUI:ClearFocus()
37 | end
38 |
39 | local function titleOnMouseDown(this)
40 | this:GetParent():StartMoving()
41 | AceGUI:ClearFocus()
42 | end
43 |
44 | local function frameOnMouseUp(this)
45 | local frame = this:GetParent()
46 | frame:StopMovingOrSizing()
47 | local self = frame.obj
48 | local status = self.status or self.localstatus
49 | status.width = frame:GetWidth()
50 | status.height = frame:GetHeight()
51 | status.top = frame:GetTop()
52 | status.left = frame:GetLeft()
53 | end
54 |
55 | local function sizerseOnMouseDown(this)
56 | this:GetParent():StartSizing("BOTTOMRIGHT")
57 | AceGUI:ClearFocus()
58 | end
59 |
60 | local function sizersOnMouseDown(this)
61 | this:GetParent():StartSizing("BOTTOM")
62 | AceGUI:ClearFocus()
63 | end
64 |
65 | local function sizereOnMouseDown(this)
66 | this:GetParent():StartSizing("RIGHT")
67 | AceGUI:ClearFocus()
68 | end
69 |
70 | local function sizerOnMouseUp(this)
71 | this:GetParent():StopMovingOrSizing()
72 | end
73 |
74 | local function SetTitle(self,title)
75 | self.titletext:SetText(title)
76 | end
77 |
78 | local function SetStatusText(self,text)
79 | -- self.statustext:SetText(text)
80 | end
81 |
82 | local function Hide(self)
83 | self.frame:Hide()
84 | end
85 |
86 | local function Show(self)
87 | self.frame:Show()
88 | end
89 |
90 | local function OnAcquire(self)
91 | self.frame:SetParent(UIParent)
92 | self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
93 | self:ApplyStatus()
94 | self:EnableResize(true)
95 | self:Show()
96 | end
97 |
98 | local function OnRelease(self)
99 | self.status = nil
100 | for k in pairs(self.localstatus) do
101 | self.localstatus[k] = nil
102 | end
103 | end
104 |
105 | -- called to set an external table to store status in
106 | local function SetStatusTable(self, status)
107 | assert(type(status) == "table")
108 | self.status = status
109 | self:ApplyStatus()
110 | end
111 |
112 | local function ApplyStatus(self)
113 | local status = self.status or self.localstatus
114 | local frame = self.frame
115 | self:SetWidth(status.width or 700)
116 | self:SetHeight(status.height or 500)
117 | if status.top and status.left then
118 | frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
119 | frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
120 | else
121 | frame:SetPoint("CENTER",UIParent,"CENTER")
122 | end
123 | end
124 |
125 | local function OnWidthSet(self, width)
126 | local content = self.content
127 | local contentwidth = width - 34
128 | if contentwidth < 0 then
129 | contentwidth = 0
130 | end
131 | content:SetWidth(contentwidth)
132 | content.width = contentwidth
133 | end
134 |
135 |
136 | local function OnHeightSet(self, height)
137 | local content = self.content
138 | local contentheight = height - 57
139 | if contentheight < 0 then
140 | contentheight = 0
141 | end
142 | content:SetHeight(contentheight)
143 | content.height = contentheight
144 | end
145 |
146 | local function EnableResize(self, state)
147 | local func = state and "Show" or "Hide"
148 | self.sizer_se[func](self.sizer_se)
149 | self.sizer_s[func](self.sizer_s)
150 | self.sizer_e[func](self.sizer_e)
151 | end
152 |
153 | local function Constructor()
154 | local frame = CreateFrame("Frame",nil,UIParent)
155 | local self = {}
156 | self.type = "Window"
157 |
158 | self.Hide = Hide
159 | self.Show = Show
160 | self.SetTitle = SetTitle
161 | self.OnRelease = OnRelease
162 | self.OnAcquire = OnAcquire
163 | self.SetStatusText = SetStatusText
164 | self.SetStatusTable = SetStatusTable
165 | self.ApplyStatus = ApplyStatus
166 | self.OnWidthSet = OnWidthSet
167 | self.OnHeightSet = OnHeightSet
168 | self.EnableResize = EnableResize
169 |
170 | self.localstatus = {}
171 |
172 | self.frame = frame
173 | frame.obj = self
174 | frame:SetWidth(700)
175 | frame:SetHeight(500)
176 | frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
177 | frame:EnableMouse()
178 | frame:SetMovable(true)
179 | frame:SetResizable(true)
180 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
181 | frame:SetScript("OnMouseDown", frameOnMouseDown)
182 |
183 | frame:SetScript("OnShow",frameOnShow)
184 | frame:SetScript("OnHide",frameOnClose)
185 | if frame.SetResizeBounds then -- WoW 10.0
186 | frame:SetResizeBounds(240,240)
187 | else
188 | frame:SetMinResize(240,240)
189 | end
190 | frame:SetToplevel(true)
191 |
192 | local titlebg = frame:CreateTexture(nil, "BACKGROUND")
193 | titlebg:SetTexture(251966) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background
194 | titlebg:SetPoint("TOPLEFT", 9, -6)
195 | titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
196 |
197 | local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
198 | dialogbg:SetTexture(137056) -- Interface\\Tooltips\\UI-Tooltip-Background
199 | dialogbg:SetPoint("TOPLEFT", 8, -24)
200 | dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
201 | dialogbg:SetVertexColor(0, 0, 0, .75)
202 |
203 | local topleft = frame:CreateTexture(nil, "BORDER")
204 | topleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
205 | topleft:SetWidth(64)
206 | topleft:SetHeight(64)
207 | topleft:SetPoint("TOPLEFT")
208 | topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
209 |
210 | local topright = frame:CreateTexture(nil, "BORDER")
211 | topright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
212 | topright:SetWidth(64)
213 | topright:SetHeight(64)
214 | topright:SetPoint("TOPRIGHT")
215 | topright:SetTexCoord(0.625, 0.75, 0, 1)
216 |
217 | local top = frame:CreateTexture(nil, "BORDER")
218 | top:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
219 | top:SetHeight(64)
220 | top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
221 | top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
222 | top:SetTexCoord(0.25, 0.369140625, 0, 1)
223 |
224 | local bottomleft = frame:CreateTexture(nil, "BORDER")
225 | bottomleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
226 | bottomleft:SetWidth(64)
227 | bottomleft:SetHeight(64)
228 | bottomleft:SetPoint("BOTTOMLEFT")
229 | bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
230 |
231 | local bottomright = frame:CreateTexture(nil, "BORDER")
232 | bottomright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
233 | bottomright:SetWidth(64)
234 | bottomright:SetHeight(64)
235 | bottomright:SetPoint("BOTTOMRIGHT")
236 | bottomright:SetTexCoord(0.875, 1, 0, 1)
237 |
238 | local bottom = frame:CreateTexture(nil, "BORDER")
239 | bottom:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
240 | bottom:SetHeight(64)
241 | bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
242 | bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
243 | bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
244 |
245 | local left = frame:CreateTexture(nil, "BORDER")
246 | left:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
247 | left:SetWidth(64)
248 | left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
249 | left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
250 | left:SetTexCoord(0.001953125, 0.125, 0, 1)
251 |
252 | local right = frame:CreateTexture(nil, "BORDER")
253 | right:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
254 | right:SetWidth(64)
255 | right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
256 | right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
257 | right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
258 |
259 | local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
260 | close:SetPoint("TOPRIGHT", 2, 1)
261 | close:SetScript("OnClick", closeOnClick)
262 | self.closebutton = close
263 | close.obj = self
264 |
265 | local titletext = frame:CreateFontString(nil, "ARTWORK")
266 | titletext:SetFontObject(GameFontNormal)
267 | titletext:SetPoint("TOPLEFT", 12, -8)
268 | titletext:SetPoint("TOPRIGHT", -32, -8)
269 | self.titletext = titletext
270 |
271 | local title = CreateFrame("Button", nil, frame)
272 | title:SetPoint("TOPLEFT", titlebg)
273 | title:SetPoint("BOTTOMRIGHT", titlebg)
274 | title:EnableMouse()
275 | title:SetScript("OnMouseDown",titleOnMouseDown)
276 | title:SetScript("OnMouseUp", frameOnMouseUp)
277 | self.title = title
278 |
279 | local sizer_se = CreateFrame("Frame",nil,frame)
280 | sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
281 | sizer_se:SetWidth(25)
282 | sizer_se:SetHeight(25)
283 | sizer_se:EnableMouse()
284 | sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
285 | sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
286 | self.sizer_se = sizer_se
287 |
288 | local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
289 | self.line1 = line1
290 | line1:SetWidth(14)
291 | line1:SetHeight(14)
292 | line1:SetPoint("BOTTOMRIGHT", -8, 8)
293 | line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
294 | local x = 0.1 * 14/17
295 | line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
296 |
297 | local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
298 | self.line2 = line2
299 | line2:SetWidth(8)
300 | line2:SetHeight(8)
301 | line2:SetPoint("BOTTOMRIGHT", -8, 8)
302 | line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
303 | x = 0.1 * 8/17
304 | line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
305 |
306 | local sizer_s = CreateFrame("Frame",nil,frame)
307 | sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
308 | sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
309 | sizer_s:SetHeight(25)
310 | sizer_s:EnableMouse()
311 | sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
312 | sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
313 | self.sizer_s = sizer_s
314 |
315 | local sizer_e = CreateFrame("Frame",nil,frame)
316 | sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
317 | sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
318 | sizer_e:SetWidth(25)
319 | sizer_e:EnableMouse()
320 | sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
321 | sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
322 | self.sizer_e = sizer_e
323 |
324 | --Container Support
325 | local content = CreateFrame("Frame",nil,frame)
326 | self.content = content
327 | content.obj = self
328 | content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
329 | content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
330 |
331 | AceGUI:RegisterAsContainer(self)
332 | return self
333 | end
334 |
335 | AceGUI:RegisterWidgetType(Type,Constructor,Version)
336 | end
337 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Button Widget
3 | Graphical Button.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Button", 24
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local _G = _G
14 | local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 | local function Button_OnClick(frame, ...)
20 | AceGUI:ClearFocus()
21 | PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
22 | frame.obj:Fire("OnClick", ...)
23 | end
24 |
25 | local function Control_OnEnter(frame)
26 | frame.obj:Fire("OnEnter")
27 | end
28 |
29 | local function Control_OnLeave(frame)
30 | frame.obj:Fire("OnLeave")
31 | end
32 |
33 | --[[-----------------------------------------------------------------------------
34 | Methods
35 | -------------------------------------------------------------------------------]]
36 | local methods = {
37 | ["OnAcquire"] = function(self)
38 | -- restore default values
39 | self:SetHeight(24)
40 | self:SetWidth(200)
41 | self:SetDisabled(false)
42 | self:SetAutoWidth(false)
43 | self:SetText()
44 | end,
45 |
46 | -- ["OnRelease"] = nil,
47 |
48 | ["SetText"] = function(self, text)
49 | self.text:SetText(text)
50 | if self.autoWidth then
51 | self:SetWidth(self.text:GetStringWidth() + 30)
52 | end
53 | end,
54 |
55 | ["SetAutoWidth"] = function(self, autoWidth)
56 | self.autoWidth = autoWidth
57 | if self.autoWidth then
58 | self:SetWidth(self.text:GetStringWidth() + 30)
59 | end
60 | end,
61 |
62 | ["SetDisabled"] = function(self, disabled)
63 | self.disabled = disabled
64 | if disabled then
65 | self.frame:Disable()
66 | else
67 | self.frame:Enable()
68 | end
69 | end
70 | }
71 |
72 | --[[-----------------------------------------------------------------------------
73 | Constructor
74 | -------------------------------------------------------------------------------]]
75 | local function Constructor()
76 | local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
77 | local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
78 | frame:Hide()
79 |
80 | frame:EnableMouse(true)
81 | frame:SetScript("OnClick", Button_OnClick)
82 | frame:SetScript("OnEnter", Control_OnEnter)
83 | frame:SetScript("OnLeave", Control_OnLeave)
84 |
85 | local text = frame:GetFontString()
86 | text:ClearAllPoints()
87 | text:SetPoint("TOPLEFT", 15, -1)
88 | text:SetPoint("BOTTOMRIGHT", -15, 1)
89 | text:SetJustifyV("MIDDLE")
90 |
91 | local widget = {
92 | text = text,
93 | frame = frame,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsWidget(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Checkbox Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "CheckBox", 26
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs = select, pairs
10 |
11 | -- WoW APIs
12 | local PlaySound = PlaySound
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Support functions
17 | -------------------------------------------------------------------------------]]
18 | local function AlignImage(self)
19 | local img = self.image:GetTexture()
20 | self.text:ClearAllPoints()
21 | if not img then
22 | self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
23 | self.text:SetPoint("RIGHT")
24 | else
25 | self.text:SetPoint("LEFT", self.image, "RIGHT", 1, 0)
26 | self.text:SetPoint("RIGHT")
27 | end
28 | end
29 |
30 | --[[-----------------------------------------------------------------------------
31 | Scripts
32 | -------------------------------------------------------------------------------]]
33 | local function Control_OnEnter(frame)
34 | frame.obj:Fire("OnEnter")
35 | end
36 |
37 | local function Control_OnLeave(frame)
38 | frame.obj:Fire("OnLeave")
39 | end
40 |
41 | local function CheckBox_OnMouseDown(frame)
42 | local self = frame.obj
43 | if not self.disabled then
44 | if self.image:GetTexture() then
45 | self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
46 | else
47 | self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
48 | end
49 | end
50 | AceGUI:ClearFocus()
51 | end
52 |
53 | local function CheckBox_OnMouseUp(frame)
54 | local self = frame.obj
55 | if not self.disabled then
56 | self:ToggleChecked()
57 |
58 | if self.checked then
59 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
60 | else -- for both nil and false (tristate)
61 | PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
62 | end
63 |
64 | self:Fire("OnValueChanged", self.checked)
65 | AlignImage(self)
66 | end
67 | end
68 |
69 | --[[-----------------------------------------------------------------------------
70 | Methods
71 | -------------------------------------------------------------------------------]]
72 | local methods = {
73 | ["OnAcquire"] = function(self)
74 | self:SetType()
75 | self:SetValue(false)
76 | self:SetTriState(nil)
77 | -- height is calculated from the width and required space for the description
78 | self:SetWidth(200)
79 | self:SetImage()
80 | self:SetDisabled(nil)
81 | self:SetDescription(nil)
82 | end,
83 |
84 | -- ["OnRelease"] = nil,
85 |
86 | ["OnWidthSet"] = function(self, width)
87 | if self.desc then
88 | self.desc:SetWidth(width - 30)
89 | if self.desc:GetText() and self.desc:GetText() ~= "" then
90 | self:SetHeight(28 + self.desc:GetStringHeight())
91 | end
92 | end
93 | end,
94 |
95 | ["SetDisabled"] = function(self, disabled)
96 | self.disabled = disabled
97 | if disabled then
98 | self.frame:Disable()
99 | self.text:SetTextColor(0.5, 0.5, 0.5)
100 | SetDesaturation(self.check, true)
101 | if self.desc then
102 | self.desc:SetTextColor(0.5, 0.5, 0.5)
103 | end
104 | else
105 | self.frame:Enable()
106 | self.text:SetTextColor(1, 1, 1)
107 | if self.tristate and self.checked == nil then
108 | SetDesaturation(self.check, true)
109 | else
110 | SetDesaturation(self.check, false)
111 | end
112 | if self.desc then
113 | self.desc:SetTextColor(1, 1, 1)
114 | end
115 | end
116 | end,
117 |
118 | ["SetValue"] = function(self, value)
119 | local check = self.check
120 | self.checked = value
121 | if value then
122 | SetDesaturation(check, false)
123 | check:Show()
124 | else
125 | --Nil is the unknown tristate value
126 | if self.tristate and value == nil then
127 | SetDesaturation(check, true)
128 | check:Show()
129 | else
130 | SetDesaturation(check, false)
131 | check:Hide()
132 | end
133 | end
134 | self:SetDisabled(self.disabled)
135 | end,
136 |
137 | ["GetValue"] = function(self)
138 | return self.checked
139 | end,
140 |
141 | ["SetTriState"] = function(self, enabled)
142 | self.tristate = enabled
143 | self:SetValue(self:GetValue())
144 | end,
145 |
146 | ["SetType"] = function(self, type)
147 | local checkbg = self.checkbg
148 | local check = self.check
149 | local highlight = self.highlight
150 |
151 | local size
152 | if type == "radio" then
153 | size = 16
154 | checkbg:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
155 | checkbg:SetTexCoord(0, 0.25, 0, 1)
156 | check:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
157 | check:SetTexCoord(0.25, 0.5, 0, 1)
158 | check:SetBlendMode("ADD")
159 | highlight:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
160 | highlight:SetTexCoord(0.5, 0.75, 0, 1)
161 | else
162 | size = 24
163 | checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
164 | checkbg:SetTexCoord(0, 1, 0, 1)
165 | check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
166 | check:SetTexCoord(0, 1, 0, 1)
167 | check:SetBlendMode("BLEND")
168 | highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
169 | highlight:SetTexCoord(0, 1, 0, 1)
170 | end
171 | checkbg:SetHeight(size)
172 | checkbg:SetWidth(size)
173 | end,
174 |
175 | ["ToggleChecked"] = function(self)
176 | local value = self:GetValue()
177 | if self.tristate then
178 | --cycle in true, nil, false order
179 | if value then
180 | self:SetValue(nil)
181 | elseif value == nil then
182 | self:SetValue(false)
183 | else
184 | self:SetValue(true)
185 | end
186 | else
187 | self:SetValue(not self:GetValue())
188 | end
189 | end,
190 |
191 | ["SetLabel"] = function(self, label)
192 | self.text:SetText(label)
193 | end,
194 |
195 | ["SetDescription"] = function(self, desc)
196 | if desc then
197 | if not self.desc then
198 | local f = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
199 | f:ClearAllPoints()
200 | f:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
201 | f:SetWidth(self.frame.width - 30)
202 | f:SetPoint("RIGHT", self.frame, "RIGHT", -30, 0)
203 | f:SetJustifyH("LEFT")
204 | f:SetJustifyV("TOP")
205 | self.desc = f
206 | end
207 | self.desc:Show()
208 | --self.text:SetFontObject(GameFontNormal)
209 | self.desc:SetText(desc)
210 | self:SetHeight(28 + self.desc:GetStringHeight())
211 | else
212 | if self.desc then
213 | self.desc:SetText("")
214 | self.desc:Hide()
215 | end
216 | --self.text:SetFontObject(GameFontHighlight)
217 | self:SetHeight(24)
218 | end
219 | end,
220 |
221 | ["SetImage"] = function(self, path, ...)
222 | local image = self.image
223 | image:SetTexture(path)
224 |
225 | if image:GetTexture() then
226 | local n = select("#", ...)
227 | if n == 4 or n == 8 then
228 | image:SetTexCoord(...)
229 | else
230 | image:SetTexCoord(0, 1, 0, 1)
231 | end
232 | end
233 | AlignImage(self)
234 | end
235 | }
236 |
237 | --[[-----------------------------------------------------------------------------
238 | Constructor
239 | -------------------------------------------------------------------------------]]
240 | local function Constructor()
241 | local frame = CreateFrame("Button", nil, UIParent)
242 | frame:Hide()
243 |
244 | frame:EnableMouse(true)
245 | frame:SetScript("OnEnter", Control_OnEnter)
246 | frame:SetScript("OnLeave", Control_OnLeave)
247 | frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
248 | frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
249 |
250 | local checkbg = frame:CreateTexture(nil, "ARTWORK")
251 | checkbg:SetWidth(24)
252 | checkbg:SetHeight(24)
253 | checkbg:SetPoint("TOPLEFT")
254 | checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
255 |
256 | local check = frame:CreateTexture(nil, "OVERLAY")
257 | check:SetAllPoints(checkbg)
258 | check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
259 |
260 | local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
261 | text:SetJustifyH("LEFT")
262 | text:SetHeight(18)
263 | text:SetPoint("LEFT", checkbg, "RIGHT")
264 | text:SetPoint("RIGHT")
265 |
266 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
267 | highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
268 | highlight:SetBlendMode("ADD")
269 | highlight:SetAllPoints(checkbg)
270 |
271 | local image = frame:CreateTexture(nil, "OVERLAY")
272 | image:SetHeight(16)
273 | image:SetWidth(16)
274 | image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
275 |
276 | local widget = {
277 | checkbg = checkbg,
278 | check = check,
279 | text = text,
280 | highlight = highlight,
281 | image = image,
282 | frame = frame,
283 | type = Type
284 | }
285 | for method, func in pairs(methods) do
286 | widget[method] = func
287 | end
288 |
289 | return AceGUI:RegisterAsWidget(widget)
290 | end
291 |
292 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
293 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ColorPicker Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "ColorPicker", 28
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | -- Unfortunately we have no way to realistically detect if a client uses inverted alpha
15 | -- as no API will tell you. Wrath uses the old colorpicker, era uses the new one, both are inverted
16 | local INVERTED_ALPHA = (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE)
17 |
18 | --[[-----------------------------------------------------------------------------
19 | Support functions
20 | -------------------------------------------------------------------------------]]
21 | local function ColorCallback(self, r, g, b, a, isAlpha)
22 | if INVERTED_ALPHA and a then
23 | a = 1 - a
24 | end
25 | if not self.HasAlpha then
26 | a = 1
27 | end
28 | -- no change, skip update
29 | if r == self.r and g == self.g and b == self.b and a == self.a then
30 | return
31 | end
32 | self:SetColor(r, g, b, a)
33 | if ColorPickerFrame:IsVisible() then
34 | --colorpicker is still open
35 | self:Fire("OnValueChanged", r, g, b, a)
36 | else
37 | --colorpicker is closed, color callback is first, ignore it,
38 | --alpha callback is the final call after it closes so confirm now
39 | if isAlpha then
40 | self:Fire("OnValueConfirmed", r, g, b, a)
41 | end
42 | end
43 | end
44 |
45 | --[[-----------------------------------------------------------------------------
46 | Scripts
47 | -------------------------------------------------------------------------------]]
48 | local function Control_OnEnter(frame)
49 | frame.obj:Fire("OnEnter")
50 | end
51 |
52 | local function Control_OnLeave(frame)
53 | frame.obj:Fire("OnLeave")
54 | end
55 |
56 | local function ColorSwatch_OnClick(frame)
57 | ColorPickerFrame:Hide()
58 | local self = frame.obj
59 | if not self.disabled then
60 | ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
61 | ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
62 | ColorPickerFrame:SetClampedToScreen(true)
63 |
64 | if ColorPickerFrame.SetupColorPickerAndShow then -- 10.2.5 color picker overhaul
65 | local r2, g2, b2, a2 = self.r, self.g, self.b, (self.a or 1)
66 | if INVERTED_ALPHA then
67 | a2 = 1 - a2
68 | end
69 |
70 | local info = {
71 | swatchFunc = function()
72 | local r, g, b = ColorPickerFrame:GetColorRGB()
73 | local a = ColorPickerFrame:GetColorAlpha()
74 | ColorCallback(self, r, g, b, a)
75 | end,
76 |
77 | hasOpacity = self.HasAlpha,
78 | opacityFunc = function()
79 | local r, g, b = ColorPickerFrame:GetColorRGB()
80 | local a = ColorPickerFrame:GetColorAlpha()
81 | ColorCallback(self, r, g, b, a, true)
82 | end,
83 | opacity = a2,
84 |
85 | cancelFunc = function()
86 | ColorCallback(self, r2, g2, b2, a2, true)
87 | end,
88 |
89 | r = r2,
90 | g = g2,
91 | b = b2,
92 | }
93 |
94 | ColorPickerFrame:SetupColorPickerAndShow(info)
95 | else
96 | ColorPickerFrame.func = function()
97 | local r, g, b = ColorPickerFrame:GetColorRGB()
98 | local a = OpacitySliderFrame:GetValue()
99 | ColorCallback(self, r, g, b, a)
100 | end
101 |
102 | ColorPickerFrame.hasOpacity = self.HasAlpha
103 | ColorPickerFrame.opacityFunc = function()
104 | local r, g, b = ColorPickerFrame:GetColorRGB()
105 | local a = OpacitySliderFrame:GetValue()
106 | ColorCallback(self, r, g, b, a, true)
107 | end
108 |
109 | local r, g, b, a = self.r, self.g, self.b, 1 - (self.a or 1)
110 | if self.HasAlpha then
111 | ColorPickerFrame.opacity = a
112 | end
113 | ColorPickerFrame:SetColorRGB(r, g, b)
114 |
115 | ColorPickerFrame.cancelFunc = function()
116 | ColorCallback(self, r, g, b, a, true)
117 | end
118 |
119 | ColorPickerFrame:Show()
120 | end
121 | end
122 | AceGUI:ClearFocus()
123 | end
124 |
125 | --[[-----------------------------------------------------------------------------
126 | Methods
127 | -------------------------------------------------------------------------------]]
128 | local methods = {
129 | ["OnAcquire"] = function(self)
130 | self:SetHeight(24)
131 | self:SetWidth(200)
132 | self:SetHasAlpha(false)
133 | self:SetColor(0, 0, 0, 1)
134 | self:SetDisabled(nil)
135 | self:SetLabel(nil)
136 | end,
137 |
138 | -- ["OnRelease"] = nil,
139 |
140 | ["SetLabel"] = function(self, text)
141 | self.text:SetText(text)
142 | end,
143 |
144 | ["SetColor"] = function(self, r, g, b, a)
145 | self.r = r
146 | self.g = g
147 | self.b = b
148 | self.a = a or 1
149 | self.colorSwatch:SetVertexColor(r, g, b, a)
150 | end,
151 |
152 | ["SetHasAlpha"] = function(self, HasAlpha)
153 | self.HasAlpha = HasAlpha
154 | end,
155 |
156 | ["SetDisabled"] = function(self, disabled)
157 | self.disabled = disabled
158 | if self.disabled then
159 | self.frame:Disable()
160 | self.text:SetTextColor(0.5, 0.5, 0.5)
161 | else
162 | self.frame:Enable()
163 | self.text:SetTextColor(1, 1, 1)
164 | end
165 | end
166 | }
167 |
168 | --[[-----------------------------------------------------------------------------
169 | Constructor
170 | -------------------------------------------------------------------------------]]
171 | local function Constructor()
172 | local frame = CreateFrame("Button", nil, UIParent)
173 | frame:Hide()
174 |
175 | frame:EnableMouse(true)
176 | frame:SetScript("OnEnter", Control_OnEnter)
177 | frame:SetScript("OnLeave", Control_OnLeave)
178 | frame:SetScript("OnClick", ColorSwatch_OnClick)
179 |
180 | local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
181 | colorSwatch:SetWidth(19)
182 | colorSwatch:SetHeight(19)
183 | colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch
184 | colorSwatch:SetPoint("LEFT")
185 |
186 | local texture = frame:CreateTexture(nil, "BACKGROUND")
187 | colorSwatch.background = texture
188 | texture:SetWidth(16)
189 | texture:SetHeight(16)
190 | texture:SetColorTexture(1, 1, 1)
191 | texture:SetPoint("CENTER", colorSwatch)
192 | texture:Show()
193 |
194 | local checkers = frame:CreateTexture(nil, "BACKGROUND")
195 | colorSwatch.checkers = checkers
196 | checkers:SetWidth(14)
197 | checkers:SetHeight(14)
198 | checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers
199 | checkers:SetTexCoord(.25, 0, 0.5, .25)
200 | checkers:SetDesaturated(true)
201 | checkers:SetVertexColor(1, 1, 1, 0.75)
202 | checkers:SetPoint("CENTER", colorSwatch)
203 | checkers:Show()
204 |
205 | local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
206 | text:SetHeight(24)
207 | text:SetJustifyH("LEFT")
208 | text:SetTextColor(1, 1, 1)
209 | text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
210 | text:SetPoint("RIGHT")
211 |
212 | --local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
213 | --highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight
214 | --highlight:SetBlendMode("ADD")
215 | --highlight:SetAllPoints(frame)
216 |
217 | local widget = {
218 | colorSwatch = colorSwatch,
219 | text = text,
220 | frame = frame,
221 | type = Type
222 | }
223 | for method, func in pairs(methods) do
224 | widget[method] = func
225 | end
226 |
227 | return AceGUI:RegisterAsWidget(widget)
228 | end
229 |
230 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
231 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | EditBox Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "EditBox", 29
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local tostring, pairs = tostring, pairs
10 |
11 | -- WoW APIs
12 | local PlaySound = PlaySound
13 | local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 | local _G = _G
16 |
17 | --[[-----------------------------------------------------------------------------
18 | Support functions
19 | -------------------------------------------------------------------------------]]
20 | if not AceGUIEditBoxInsertLink then
21 | -- upgradeable hook
22 | hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
23 | end
24 |
25 | function _G.AceGUIEditBoxInsertLink(text)
26 | for i = 1, AceGUI:GetWidgetCount(Type) do
27 | local editbox = _G["AceGUI-3.0EditBox"..i]
28 | if editbox and editbox:IsVisible() and editbox:HasFocus() then
29 | editbox:Insert(text)
30 | return true
31 | end
32 | end
33 | end
34 |
35 | local function ShowButton(self)
36 | if not self.disablebutton then
37 | self.button:Show()
38 | self.editbox:SetTextInsets(0, 20, 3, 3)
39 | end
40 | end
41 |
42 | local function HideButton(self)
43 | self.button:Hide()
44 | self.editbox:SetTextInsets(0, 0, 3, 3)
45 | end
46 |
47 | --[[-----------------------------------------------------------------------------
48 | Scripts
49 | -------------------------------------------------------------------------------]]
50 | local function Control_OnEnter(frame)
51 | frame.obj:Fire("OnEnter")
52 | end
53 |
54 | local function Control_OnLeave(frame)
55 | frame.obj:Fire("OnLeave")
56 | end
57 |
58 | local function Frame_OnShowFocus(frame)
59 | frame.obj.editbox:SetFocus()
60 | frame:SetScript("OnShow", nil)
61 | end
62 |
63 | local function EditBox_OnEscapePressed(frame)
64 | AceGUI:ClearFocus()
65 | end
66 |
67 | local function EditBox_OnEnterPressed(frame)
68 | local self = frame.obj
69 | local value = frame:GetText()
70 | local cancel = self:Fire("OnEnterPressed", value)
71 | if not cancel then
72 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
73 | HideButton(self)
74 | end
75 | end
76 |
77 | local function EditBox_OnReceiveDrag(frame)
78 | local self = frame.obj
79 | local type, id, info, extra = GetCursorInfo()
80 | local name
81 | if type == "item" then
82 | name = info
83 | elseif type == "spell" then
84 | if C_Spell and C_Spell.GetSpellName then
85 | name = C_Spell.GetSpellName(extra)
86 | else
87 | name = GetSpellInfo(id, info)
88 | end
89 | elseif type == "macro" then
90 | name = GetMacroInfo(id)
91 | end
92 | if name then
93 | self:SetText(name)
94 | self:Fire("OnEnterPressed", name)
95 | ClearCursor()
96 | HideButton(self)
97 | AceGUI:ClearFocus()
98 | end
99 | end
100 |
101 | local function EditBox_OnTextChanged(frame)
102 | local self = frame.obj
103 | local value = frame:GetText()
104 | if tostring(value) ~= tostring(self.lasttext) then
105 | self:Fire("OnTextChanged", value)
106 | self.lasttext = value
107 | ShowButton(self)
108 | end
109 | end
110 |
111 | local function EditBox_OnFocusGained(frame)
112 | AceGUI:SetFocus(frame.obj)
113 | end
114 |
115 | local function Button_OnClick(frame)
116 | local editbox = frame.obj.editbox
117 | editbox:ClearFocus()
118 | EditBox_OnEnterPressed(editbox)
119 | end
120 |
121 | --[[-----------------------------------------------------------------------------
122 | Methods
123 | -------------------------------------------------------------------------------]]
124 | local methods = {
125 | ["OnAcquire"] = function(self)
126 | -- height is controlled by SetLabel
127 | self:SetWidth(200)
128 | self:SetDisabled(false)
129 | self:SetLabel()
130 | self:SetText()
131 | self:DisableButton(false)
132 | self:SetMaxLetters(0)
133 | end,
134 |
135 | ["OnRelease"] = function(self)
136 | self:ClearFocus()
137 | end,
138 |
139 | ["SetDisabled"] = function(self, disabled)
140 | self.disabled = disabled
141 | if disabled then
142 | self.editbox:EnableMouse(false)
143 | self.editbox:ClearFocus()
144 | self.editbox:SetTextColor(0.5,0.5,0.5)
145 | self.label:SetTextColor(0.5,0.5,0.5)
146 | else
147 | self.editbox:EnableMouse(true)
148 | self.editbox:SetTextColor(1,1,1)
149 | self.label:SetTextColor(1,.82,0)
150 | end
151 | end,
152 |
153 | ["SetText"] = function(self, text)
154 | self.lasttext = text or ""
155 | self.editbox:SetText(text or "")
156 | self.editbox:SetCursorPosition(0)
157 | HideButton(self)
158 | end,
159 |
160 | ["GetText"] = function(self, text)
161 | return self.editbox:GetText()
162 | end,
163 |
164 | ["SetLabel"] = function(self, text)
165 | if text and text ~= "" then
166 | self.label:SetText(text)
167 | self.label:Show()
168 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
169 | self:SetHeight(44)
170 | self.alignoffset = 30
171 | else
172 | self.label:SetText("")
173 | self.label:Hide()
174 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
175 | self:SetHeight(26)
176 | self.alignoffset = 12
177 | end
178 | end,
179 |
180 | ["DisableButton"] = function(self, disabled)
181 | self.disablebutton = disabled
182 | if disabled then
183 | HideButton(self)
184 | end
185 | end,
186 |
187 | ["SetMaxLetters"] = function (self, num)
188 | self.editbox:SetMaxLetters(num or 0)
189 | end,
190 |
191 | ["ClearFocus"] = function(self)
192 | self.editbox:ClearFocus()
193 | self.frame:SetScript("OnShow", nil)
194 | end,
195 |
196 | ["SetFocus"] = function(self)
197 | self.editbox:SetFocus()
198 | if not self.frame:IsShown() then
199 | self.frame:SetScript("OnShow", Frame_OnShowFocus)
200 | end
201 | end,
202 |
203 | ["HighlightText"] = function(self, from, to)
204 | self.editbox:HighlightText(from, to)
205 | end
206 | }
207 |
208 | --[[-----------------------------------------------------------------------------
209 | Constructor
210 | -------------------------------------------------------------------------------]]
211 | local function Constructor()
212 | local num = AceGUI:GetNextWidgetNum(Type)
213 | local frame = CreateFrame("Frame", nil, UIParent)
214 | frame:Hide()
215 |
216 | local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
217 | editbox:SetAutoFocus(false)
218 | editbox:SetFontObject(ChatFontNormal)
219 | editbox:SetScript("OnEnter", Control_OnEnter)
220 | editbox:SetScript("OnLeave", Control_OnLeave)
221 | editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
222 | editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
223 | editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
224 | editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
225 | editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
226 | editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
227 | editbox:SetTextInsets(0, 0, 3, 3)
228 | editbox:SetMaxLetters(256)
229 | editbox:SetPoint("BOTTOMLEFT", 6, 0)
230 | editbox:SetPoint("BOTTOMRIGHT")
231 | editbox:SetHeight(19)
232 |
233 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
234 | label:SetPoint("TOPLEFT", 0, -2)
235 | label:SetPoint("TOPRIGHT", 0, -2)
236 | label:SetJustifyH("LEFT")
237 | label:SetHeight(18)
238 |
239 | local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
240 | button:SetWidth(40)
241 | button:SetHeight(20)
242 | button:SetPoint("RIGHT", -2, 0)
243 | button:SetText(OKAY)
244 | button:SetScript("OnClick", Button_OnClick)
245 | button:Hide()
246 |
247 | local widget = {
248 | alignoffset = 30,
249 | editbox = editbox,
250 | label = label,
251 | button = button,
252 | frame = frame,
253 | type = Type
254 | }
255 | for method, func in pairs(methods) do
256 | widget[method] = func
257 | end
258 | editbox.obj, button.obj = widget, widget
259 |
260 | return AceGUI:RegisterAsWidget(widget)
261 | end
262 |
263 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
264 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Heading Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Heading", 20
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Methods
16 | -------------------------------------------------------------------------------]]
17 | local methods = {
18 | ["OnAcquire"] = function(self)
19 | self:SetText()
20 | self:SetFullWidth()
21 | self:SetHeight(18)
22 | end,
23 |
24 | -- ["OnRelease"] = nil,
25 |
26 | ["SetText"] = function(self, text)
27 | self.label:SetText(text or "")
28 | if text and text ~= "" then
29 | self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
30 | self.right:Show()
31 | else
32 | self.left:SetPoint("RIGHT", -3, 0)
33 | self.right:Hide()
34 | end
35 | end
36 | }
37 |
38 | --[[-----------------------------------------------------------------------------
39 | Constructor
40 | -------------------------------------------------------------------------------]]
41 | local function Constructor()
42 | local frame = CreateFrame("Frame", nil, UIParent)
43 | frame:Hide()
44 |
45 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
46 | label:SetPoint("TOP")
47 | label:SetPoint("BOTTOM")
48 | label:SetJustifyH("CENTER")
49 |
50 | local left = frame:CreateTexture(nil, "BACKGROUND")
51 | left:SetHeight(8)
52 | left:SetPoint("LEFT", 3, 0)
53 | left:SetPoint("RIGHT", label, "LEFT", -5, 0)
54 | left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
55 | left:SetTexCoord(0.81, 0.94, 0.5, 1)
56 |
57 | local right = frame:CreateTexture(nil, "BACKGROUND")
58 | right:SetHeight(8)
59 | right:SetPoint("RIGHT", -3, 0)
60 | right:SetPoint("LEFT", label, "RIGHT", 5, 0)
61 | right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
62 | right:SetTexCoord(0.81, 0.94, 0.5, 1)
63 |
64 | local widget = {
65 | label = label,
66 | left = left,
67 | right = right,
68 | frame = frame,
69 | type = Type
70 | }
71 | for method, func in pairs(methods) do
72 | widget[method] = func
73 | end
74 |
75 | return AceGUI:RegisterAsWidget(widget)
76 | end
77 |
78 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
79 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Icon Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Icon", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs, print = select, pairs, print
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Scripts
16 | -------------------------------------------------------------------------------]]
17 | local function Control_OnEnter(frame)
18 | frame.obj:Fire("OnEnter")
19 | end
20 |
21 | local function Control_OnLeave(frame)
22 | frame.obj:Fire("OnLeave")
23 | end
24 |
25 | local function Button_OnClick(frame, button)
26 | frame.obj:Fire("OnClick", button)
27 | AceGUI:ClearFocus()
28 | end
29 |
30 | --[[-----------------------------------------------------------------------------
31 | Methods
32 | -------------------------------------------------------------------------------]]
33 | local methods = {
34 | ["OnAcquire"] = function(self)
35 | self:SetHeight(110)
36 | self:SetWidth(110)
37 | self:SetLabel()
38 | self:SetImage(nil)
39 | self:SetImageSize(64, 64)
40 | self:SetDisabled(false)
41 | end,
42 |
43 | -- ["OnRelease"] = nil,
44 |
45 | ["SetLabel"] = function(self, text)
46 | if text and text ~= "" then
47 | self.label:Show()
48 | self.label:SetText(text)
49 | self:SetHeight(self.image:GetHeight() + 25)
50 | else
51 | self.label:Hide()
52 | self:SetHeight(self.image:GetHeight() + 10)
53 | end
54 | end,
55 |
56 | ["SetImage"] = function(self, path, ...)
57 | local image = self.image
58 | image:SetTexture(path)
59 |
60 | if image:GetTexture() then
61 | local n = select("#", ...)
62 | if n == 4 or n == 8 then
63 | image:SetTexCoord(...)
64 | else
65 | image:SetTexCoord(0, 1, 0, 1)
66 | end
67 | end
68 | end,
69 |
70 | ["SetImageSize"] = function(self, width, height)
71 | self.image:SetWidth(width)
72 | self.image:SetHeight(height)
73 | --self.frame:SetWidth(width + 30)
74 | if self.label:IsShown() then
75 | self:SetHeight(height + 25)
76 | else
77 | self:SetHeight(height + 10)
78 | end
79 | end,
80 |
81 | ["SetDisabled"] = function(self, disabled)
82 | self.disabled = disabled
83 | if disabled then
84 | self.frame:Disable()
85 | self.label:SetTextColor(0.5, 0.5, 0.5)
86 | self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
87 | else
88 | self.frame:Enable()
89 | self.label:SetTextColor(1, 1, 1)
90 | self.image:SetVertexColor(1, 1, 1, 1)
91 | end
92 | end
93 | }
94 |
95 | --[[-----------------------------------------------------------------------------
96 | Constructor
97 | -------------------------------------------------------------------------------]]
98 | local function Constructor()
99 | local frame = CreateFrame("Button", nil, UIParent)
100 | frame:Hide()
101 |
102 | frame:EnableMouse(true)
103 | frame:SetScript("OnEnter", Control_OnEnter)
104 | frame:SetScript("OnLeave", Control_OnLeave)
105 | frame:SetScript("OnClick", Button_OnClick)
106 |
107 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
108 | label:SetPoint("BOTTOMLEFT")
109 | label:SetPoint("BOTTOMRIGHT")
110 | label:SetJustifyH("CENTER")
111 | label:SetJustifyV("TOP")
112 | label:SetHeight(18)
113 |
114 | local image = frame:CreateTexture(nil, "BACKGROUND")
115 | image:SetWidth(64)
116 | image:SetHeight(64)
117 | image:SetPoint("TOP", 0, -5)
118 |
119 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
120 | highlight:SetAllPoints(image)
121 | highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight
122 | highlight:SetTexCoord(0, 1, 0.23, 0.77)
123 | highlight:SetBlendMode("ADD")
124 |
125 | local widget = {
126 | label = label,
127 | image = image,
128 | frame = frame,
129 | type = Type
130 | }
131 | for method, func in pairs(methods) do
132 | widget[method] = func
133 | end
134 |
135 | widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
136 |
137 | return AceGUI:RegisterAsWidget(widget)
138 | end
139 |
140 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
141 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InteractiveLabel Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "InteractiveLabel", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs = select, pairs
10 |
11 | --[[-----------------------------------------------------------------------------
12 | Scripts
13 | -------------------------------------------------------------------------------]]
14 | local function Control_OnEnter(frame)
15 | frame.obj:Fire("OnEnter")
16 | end
17 |
18 | local function Control_OnLeave(frame)
19 | frame.obj:Fire("OnLeave")
20 | end
21 |
22 | local function Label_OnClick(frame, button)
23 | frame.obj:Fire("OnClick", button)
24 | AceGUI:ClearFocus()
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Methods
29 | -------------------------------------------------------------------------------]]
30 | local methods = {
31 | ["OnAcquire"] = function(self)
32 | self:LabelOnAcquire()
33 | self:SetHighlight()
34 | self:SetHighlightTexCoord()
35 | self:SetDisabled(false)
36 | end,
37 |
38 | -- ["OnRelease"] = nil,
39 |
40 | ["SetHighlight"] = function(self, ...)
41 | self.highlight:SetTexture(...)
42 | end,
43 |
44 | ["SetHighlightTexCoord"] = function(self, ...)
45 | local c = select("#", ...)
46 | if c == 4 or c == 8 then
47 | self.highlight:SetTexCoord(...)
48 | else
49 | self.highlight:SetTexCoord(0, 1, 0, 1)
50 | end
51 | end,
52 |
53 | ["SetDisabled"] = function(self,disabled)
54 | self.disabled = disabled
55 | if disabled then
56 | self.frame:EnableMouse(false)
57 | self.label:SetTextColor(0.5, 0.5, 0.5)
58 | else
59 | self.frame:EnableMouse(true)
60 | self.label:SetTextColor(1, 1, 1)
61 | end
62 | end
63 | }
64 |
65 | --[[-----------------------------------------------------------------------------
66 | Constructor
67 | -------------------------------------------------------------------------------]]
68 | local function Constructor()
69 | -- create a Label type that we will hijack
70 | local label = AceGUI:Create("Label")
71 |
72 | local frame = label.frame
73 | frame:EnableMouse(true)
74 | frame:SetScript("OnEnter", Control_OnEnter)
75 | frame:SetScript("OnLeave", Control_OnLeave)
76 | frame:SetScript("OnMouseDown", Label_OnClick)
77 |
78 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
79 | highlight:SetTexture(nil)
80 | highlight:SetAllPoints()
81 | highlight:SetBlendMode("ADD")
82 |
83 | label.highlight = highlight
84 | label.type = Type
85 | label.LabelOnAcquire = label.OnAcquire
86 | for method, func in pairs(methods) do
87 | label[method] = func
88 | end
89 |
90 | return label
91 | end
92 |
93 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
94 |
95 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Keybinding Widget
3 | Set Keybindings in the Config UI.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Keybinding", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 |
20 | local function Control_OnEnter(frame)
21 | frame.obj:Fire("OnEnter")
22 | end
23 |
24 | local function Control_OnLeave(frame)
25 | frame.obj:Fire("OnLeave")
26 | end
27 |
28 | local function Keybinding_OnClick(frame, button)
29 | if button == "LeftButton" or button == "RightButton" then
30 | local self = frame.obj
31 | if self.waitingForKey then
32 | frame:EnableKeyboard(false)
33 | frame:EnableMouseWheel(false)
34 | self.msgframe:Hide()
35 | frame:UnlockHighlight()
36 | self.waitingForKey = nil
37 | else
38 | frame:EnableKeyboard(true)
39 | frame:EnableMouseWheel(true)
40 | self.msgframe:Show()
41 | frame:LockHighlight()
42 | self.waitingForKey = true
43 | end
44 | end
45 | AceGUI:ClearFocus()
46 | end
47 |
48 | local ignoreKeys = {
49 | ["BUTTON1"] = true, ["BUTTON2"] = true,
50 | ["UNKNOWN"] = true,
51 | ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
52 | ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
53 | }
54 | local function Keybinding_OnKeyDown(frame, key)
55 | local self = frame.obj
56 | if self.waitingForKey then
57 | local keyPressed = key
58 | if keyPressed == "ESCAPE" then
59 | keyPressed = ""
60 | else
61 | if ignoreKeys[keyPressed] then return end
62 | if IsShiftKeyDown() then
63 | keyPressed = "SHIFT-"..keyPressed
64 | end
65 | if IsControlKeyDown() then
66 | keyPressed = "CTRL-"..keyPressed
67 | end
68 | if IsAltKeyDown() then
69 | keyPressed = "ALT-"..keyPressed
70 | end
71 | end
72 |
73 | frame:EnableKeyboard(false)
74 | frame:EnableMouseWheel(false)
75 | self.msgframe:Hide()
76 | frame:UnlockHighlight()
77 | self.waitingForKey = nil
78 |
79 | if not self.disabled then
80 | self:SetKey(keyPressed)
81 | self:Fire("OnKeyChanged", keyPressed)
82 | end
83 | end
84 | end
85 |
86 | local function Keybinding_OnMouseDown(frame, button)
87 | if button == "LeftButton" or button == "RightButton" then
88 | return
89 | elseif button == "MiddleButton" then
90 | button = "BUTTON3"
91 | elseif button == "Button4" then
92 | button = "BUTTON4"
93 | elseif button == "Button5" then
94 | button = "BUTTON5"
95 | end
96 | Keybinding_OnKeyDown(frame, button)
97 | end
98 |
99 | local function Keybinding_OnMouseWheel(frame, direction)
100 | local button
101 | if direction >= 0 then
102 | button = "MOUSEWHEELUP"
103 | else
104 | button = "MOUSEWHEELDOWN"
105 | end
106 | Keybinding_OnKeyDown(frame, button)
107 | end
108 |
109 | --[[-----------------------------------------------------------------------------
110 | Methods
111 | -------------------------------------------------------------------------------]]
112 | local methods = {
113 | ["OnAcquire"] = function(self)
114 | self:SetWidth(200)
115 | self:SetLabel("")
116 | self:SetKey("")
117 | self.waitingForKey = nil
118 | self.msgframe:Hide()
119 | self:SetDisabled(false)
120 | self.button:EnableKeyboard(false)
121 | self.button:EnableMouseWheel(false)
122 | end,
123 |
124 | -- ["OnRelease"] = nil,
125 |
126 | ["SetDisabled"] = function(self, disabled)
127 | self.disabled = disabled
128 | if disabled then
129 | self.button:Disable()
130 | self.label:SetTextColor(0.5,0.5,0.5)
131 | else
132 | self.button:Enable()
133 | self.label:SetTextColor(1,1,1)
134 | end
135 | end,
136 |
137 | ["SetKey"] = function(self, key)
138 | if (key or "") == "" then
139 | self.button:SetText(NOT_BOUND)
140 | self.button:SetNormalFontObject("GameFontNormal")
141 | else
142 | self.button:SetText(key)
143 | self.button:SetNormalFontObject("GameFontHighlight")
144 | end
145 | end,
146 |
147 | ["GetKey"] = function(self)
148 | local key = self.button:GetText()
149 | if key == NOT_BOUND then
150 | key = nil
151 | end
152 | return key
153 | end,
154 |
155 | ["SetLabel"] = function(self, label)
156 | self.label:SetText(label or "")
157 | if (label or "") == "" then
158 | self.alignoffset = nil
159 | self:SetHeight(24)
160 | else
161 | self.alignoffset = 30
162 | self:SetHeight(44)
163 | end
164 | end,
165 | }
166 |
167 | --[[-----------------------------------------------------------------------------
168 | Constructor
169 | -------------------------------------------------------------------------------]]
170 |
171 | local ControlBackdrop = {
172 | bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
173 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
174 | tile = true, tileSize = 16, edgeSize = 16,
175 | insets = { left = 3, right = 3, top = 3, bottom = 3 }
176 | }
177 |
178 | local function keybindingMsgFixWidth(frame)
179 | frame:SetWidth(frame.msg:GetWidth() + 10)
180 | frame:SetScript("OnUpdate", nil)
181 | end
182 |
183 | local function Constructor()
184 | local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
185 |
186 | local frame = CreateFrame("Frame", nil, UIParent)
187 | local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
188 |
189 | button:EnableMouse(true)
190 | button:EnableMouseWheel(false)
191 | button:RegisterForClicks("AnyDown")
192 | button:SetScript("OnEnter", Control_OnEnter)
193 | button:SetScript("OnLeave", Control_OnLeave)
194 | button:SetScript("OnClick", Keybinding_OnClick)
195 | button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
196 | button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
197 | button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
198 | button:SetPoint("BOTTOMLEFT")
199 | button:SetPoint("BOTTOMRIGHT")
200 | button:SetHeight(24)
201 | button:EnableKeyboard(false)
202 |
203 | local text = button:GetFontString()
204 | text:SetPoint("LEFT", 7, 0)
205 | text:SetPoint("RIGHT", -7, 0)
206 |
207 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
208 | label:SetPoint("TOPLEFT")
209 | label:SetPoint("TOPRIGHT")
210 | label:SetJustifyH("CENTER")
211 | label:SetHeight(18)
212 |
213 | local msgframe = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
214 | msgframe:SetHeight(30)
215 | msgframe:SetBackdrop(ControlBackdrop)
216 | msgframe:SetBackdropColor(0,0,0)
217 | msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
218 | msgframe:SetFrameLevel(1000)
219 | msgframe:SetToplevel(true)
220 |
221 | local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
222 | msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
223 | msgframe.msg = msg
224 | msg:SetPoint("TOPLEFT", 5, -5)
225 | msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
226 | msgframe:SetPoint("BOTTOM", button, "TOP")
227 | msgframe:Hide()
228 |
229 | local widget = {
230 | button = button,
231 | label = label,
232 | msgframe = msgframe,
233 | frame = frame,
234 | alignoffset = 30,
235 | type = Type
236 | }
237 | for method, func in pairs(methods) do
238 | widget[method] = func
239 | end
240 | button.obj = widget
241 |
242 | return AceGUI:RegisterAsWidget(widget)
243 | end
244 |
245 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
246 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Label Widget
3 | Displays text and optionally an icon.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Label", 28
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local max, select, pairs = math.max, select, pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Support functions
17 | -------------------------------------------------------------------------------]]
18 |
19 | local function UpdateImageAnchor(self)
20 | if self.resizing then return end
21 | local frame = self.frame
22 | local width = frame.width or frame:GetWidth() or 0
23 | local image = self.image
24 | local label = self.label
25 | local height
26 |
27 | label:ClearAllPoints()
28 | image:ClearAllPoints()
29 |
30 | if self.imageshown then
31 | local imagewidth = image:GetWidth()
32 | if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
33 | -- image goes on top centered when less than 200 width for the text, or if there is no text
34 | image:SetPoint("TOP")
35 | label:SetPoint("TOP", image, "BOTTOM")
36 | label:SetPoint("LEFT")
37 | label:SetWidth(width)
38 | height = image:GetHeight() + label:GetStringHeight()
39 | else
40 | -- image on the left
41 | image:SetPoint("TOPLEFT")
42 | if image:GetHeight() > label:GetStringHeight() then
43 | label:SetPoint("LEFT", image, "RIGHT", 4, 0)
44 | else
45 | label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
46 | end
47 | label:SetWidth(width - imagewidth - 4)
48 | height = max(image:GetHeight(), label:GetStringHeight())
49 | end
50 | else
51 | -- no image shown
52 | label:SetPoint("TOPLEFT")
53 | label:SetWidth(width)
54 | height = label:GetStringHeight()
55 | end
56 |
57 | -- avoid zero-height labels, since they can used as spacers
58 | if not height or height == 0 then
59 | height = 1
60 | end
61 |
62 | self.resizing = true
63 | frame:SetHeight(height)
64 | frame.height = height
65 | self.resizing = nil
66 | end
67 |
68 | --[[-----------------------------------------------------------------------------
69 | Methods
70 | -------------------------------------------------------------------------------]]
71 | local methods = {
72 | ["OnAcquire"] = function(self)
73 | -- set the flag to stop constant size updates
74 | self.resizing = true
75 | -- height is set dynamically by the text and image size
76 | self:SetWidth(200)
77 | self:SetText()
78 | self:SetImage(nil)
79 | self:SetImageSize(16, 16)
80 | self:SetColor()
81 | self:SetFontObject()
82 | self:SetJustifyH("LEFT")
83 | self:SetJustifyV("TOP")
84 |
85 | -- reset the flag
86 | self.resizing = nil
87 | -- run the update explicitly
88 | UpdateImageAnchor(self)
89 | end,
90 |
91 | -- ["OnRelease"] = nil,
92 |
93 | ["OnWidthSet"] = function(self, width)
94 | UpdateImageAnchor(self)
95 | end,
96 |
97 | ["SetText"] = function(self, text)
98 | self.label:SetText(text)
99 | UpdateImageAnchor(self)
100 | end,
101 |
102 | ["SetColor"] = function(self, r, g, b)
103 | if not (r and g and b) then
104 | r, g, b = 1, 1, 1
105 | end
106 | self.label:SetVertexColor(r, g, b)
107 | end,
108 |
109 | ["SetImage"] = function(self, path, ...)
110 | local image = self.image
111 | image:SetTexture(path)
112 |
113 | if image:GetTexture() then
114 | self.imageshown = true
115 | local n = select("#", ...)
116 | if n == 4 or n == 8 then
117 | image:SetTexCoord(...)
118 | else
119 | image:SetTexCoord(0, 1, 0, 1)
120 | end
121 | else
122 | self.imageshown = nil
123 | end
124 | UpdateImageAnchor(self)
125 | end,
126 |
127 | ["SetFont"] = function(self, font, height, flags)
128 | if not self.fontObject then
129 | self.fontObject = CreateFont("AceGUI30LabelFont" .. AceGUI:GetNextWidgetNum(Type))
130 | end
131 | self.fontObject:SetFont(font, height, flags)
132 | self:SetFontObject(self.fontObject)
133 | end,
134 |
135 | ["SetFontObject"] = function(self, font)
136 | self.label:SetFontObject(font or GameFontHighlightSmall)
137 | UpdateImageAnchor(self)
138 | end,
139 |
140 | ["SetImageSize"] = function(self, width, height)
141 | self.image:SetWidth(width)
142 | self.image:SetHeight(height)
143 | UpdateImageAnchor(self)
144 | end,
145 |
146 | ["SetJustifyH"] = function(self, justifyH)
147 | self.label:SetJustifyH(justifyH)
148 | end,
149 |
150 | ["SetJustifyV"] = function(self, justifyV)
151 | self.label:SetJustifyV(justifyV)
152 | end,
153 | }
154 |
155 | --[[-----------------------------------------------------------------------------
156 | Constructor
157 | -------------------------------------------------------------------------------]]
158 | local function Constructor()
159 | local frame = CreateFrame("Frame", nil, UIParent)
160 | frame:Hide()
161 |
162 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
163 | local image = frame:CreateTexture(nil, "BACKGROUND")
164 |
165 | -- create widget
166 | local widget = {
167 | label = label,
168 | image = image,
169 | frame = frame,
170 | type = Type
171 | }
172 | for method, func in pairs(methods) do
173 | widget[method] = func
174 | end
175 |
176 | return AceGUI:RegisterAsWidget(widget)
177 | end
178 |
179 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
180 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua:
--------------------------------------------------------------------------------
1 | local Type, Version = "MultiLineEditBox", 33
2 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
3 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
4 |
5 | -- Lua APIs
6 | local pairs = pairs
7 |
8 | -- WoW APIs
9 | local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
10 | local CreateFrame, UIParent = CreateFrame, UIParent
11 | local _G = _G
12 |
13 | --[[-----------------------------------------------------------------------------
14 | Support functions
15 | -------------------------------------------------------------------------------]]
16 |
17 | if not AceGUIMultiLineEditBoxInsertLink then
18 | -- upgradeable hook
19 | hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
20 | end
21 |
22 | function _G.AceGUIMultiLineEditBoxInsertLink(text)
23 | for i = 1, AceGUI:GetWidgetCount(Type) do
24 | local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
25 | if editbox and editbox:IsVisible() and editbox:HasFocus() then
26 | editbox:Insert(text)
27 | return true
28 | end
29 | end
30 | end
31 |
32 |
33 | local function Layout(self)
34 | self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
35 |
36 | if self.labelHeight == 0 then
37 | self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
38 | else
39 | self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
40 | end
41 |
42 | if self.disablebutton then
43 | self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
44 | self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
45 | else
46 | self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
47 | self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
48 | end
49 | end
50 |
51 | --[[-----------------------------------------------------------------------------
52 | Scripts
53 | -------------------------------------------------------------------------------]]
54 | local function OnClick(self) -- Button
55 | self = self.obj
56 | self.editBox:ClearFocus()
57 | if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
58 | self.button:Disable()
59 | end
60 | end
61 |
62 | local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
63 | self, y = self.obj.scrollFrame, -y
64 | local offset = self:GetVerticalScroll()
65 | if y < offset then
66 | self:SetVerticalScroll(y)
67 | else
68 | y = y + cursorHeight - self:GetHeight()
69 | if y > offset then
70 | self:SetVerticalScroll(y)
71 | end
72 | end
73 | end
74 |
75 | local function OnEditFocusLost(self) -- EditBox
76 | self:HighlightText(0, 0)
77 | self.obj:Fire("OnEditFocusLost")
78 | end
79 |
80 | local function OnEnter(self) -- EditBox / ScrollFrame
81 | self = self.obj
82 | if not self.entered then
83 | self.entered = true
84 | self:Fire("OnEnter")
85 | end
86 | end
87 |
88 | local function OnLeave(self) -- EditBox / ScrollFrame
89 | self = self.obj
90 | if self.entered then
91 | self.entered = nil
92 | self:Fire("OnLeave")
93 | end
94 | end
95 |
96 | local function OnMouseUp(self) -- ScrollFrame
97 | self = self.obj.editBox
98 | self:SetFocus()
99 | self:SetCursorPosition(self:GetNumLetters())
100 | end
101 |
102 | local function OnReceiveDrag(self) -- EditBox / ScrollFrame
103 | local type, id, info, extra = GetCursorInfo()
104 | if type == "spell" then
105 | if C_Spell and C_Spell.GetSpellName then
106 | info = C_Spell.GetSpellName(extra)
107 | else
108 | info = GetSpellInfo(id, info)
109 | end
110 | elseif type ~= "item" then
111 | return
112 | end
113 | ClearCursor()
114 | self = self.obj
115 | local editBox = self.editBox
116 | if not editBox:HasFocus() then
117 | editBox:SetFocus()
118 | editBox:SetCursorPosition(editBox:GetNumLetters())
119 | end
120 | editBox:Insert(info)
121 | self.button:Enable()
122 | end
123 |
124 | local function OnSizeChanged(self, width, height) -- ScrollFrame
125 | self.obj.editBox:SetWidth(width)
126 | end
127 |
128 | local function OnTextChanged(self, userInput) -- EditBox
129 | if userInput then
130 | self = self.obj
131 | self:Fire("OnTextChanged", self.editBox:GetText())
132 | self.button:Enable()
133 | end
134 | end
135 |
136 | local function OnTextSet(self) -- EditBox
137 | self:HighlightText(0, 0)
138 | self:SetCursorPosition(self:GetNumLetters())
139 | self:SetCursorPosition(0)
140 | self.obj.button:Disable()
141 | end
142 |
143 | local function OnVerticalScroll(self, offset) -- ScrollFrame
144 | local editBox = self.obj.editBox
145 | editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
146 | end
147 |
148 | local function OnScrollRangeChanged(self, xrange, yrange)
149 | if yrange == 0 then
150 | self.obj.editBox:SetHitRectInsets(0, 0, 0, 0)
151 | else
152 | OnVerticalScroll(self, self:GetVerticalScroll())
153 | end
154 | end
155 |
156 | local function OnShowFocus(frame)
157 | frame.obj.editBox:SetFocus()
158 | frame:SetScript("OnShow", nil)
159 | end
160 |
161 | local function OnEditFocusGained(frame)
162 | AceGUI:SetFocus(frame.obj)
163 | frame.obj:Fire("OnEditFocusGained")
164 | end
165 |
166 | --[[-----------------------------------------------------------------------------
167 | Methods
168 | -------------------------------------------------------------------------------]]
169 | local methods = {
170 | ["OnAcquire"] = function(self)
171 | self.editBox:SetText("")
172 | self:SetDisabled(false)
173 | self:SetWidth(200)
174 | self:DisableButton(false)
175 | self:SetNumLines()
176 | self.entered = nil
177 | self:SetMaxLetters(0)
178 | end,
179 |
180 | ["OnRelease"] = function(self)
181 | self:ClearFocus()
182 | end,
183 |
184 | ["SetDisabled"] = function(self, disabled)
185 | local editBox = self.editBox
186 | if disabled then
187 | editBox:ClearFocus()
188 | editBox:EnableMouse(false)
189 | editBox:SetTextColor(0.5, 0.5, 0.5)
190 | self.label:SetTextColor(0.5, 0.5, 0.5)
191 | self.scrollFrame:EnableMouse(false)
192 | self.button:Disable()
193 | else
194 | editBox:EnableMouse(true)
195 | editBox:SetTextColor(1, 1, 1)
196 | self.label:SetTextColor(1, 0.82, 0)
197 | self.scrollFrame:EnableMouse(true)
198 | end
199 | end,
200 |
201 | ["SetLabel"] = function(self, text)
202 | if text and text ~= "" then
203 | self.label:SetText(text)
204 | if self.labelHeight ~= 10 then
205 | self.labelHeight = 10
206 | self.label:Show()
207 | end
208 | elseif self.labelHeight ~= 0 then
209 | self.labelHeight = 0
210 | self.label:Hide()
211 | end
212 | Layout(self)
213 | end,
214 |
215 | ["SetNumLines"] = function(self, value)
216 | if not value or value < 4 then
217 | value = 4
218 | end
219 | self.numlines = value
220 | Layout(self)
221 | end,
222 |
223 | ["SetText"] = function(self, text)
224 | self.editBox:SetText(text)
225 | end,
226 |
227 | ["GetText"] = function(self)
228 | return self.editBox:GetText()
229 | end,
230 |
231 | ["SetMaxLetters"] = function (self, num)
232 | self.editBox:SetMaxLetters(num or 0)
233 | end,
234 |
235 | ["DisableButton"] = function(self, disabled)
236 | self.disablebutton = disabled
237 | if disabled then
238 | self.button:Hide()
239 | else
240 | self.button:Show()
241 | end
242 | Layout(self)
243 | end,
244 |
245 | ["ClearFocus"] = function(self)
246 | self.editBox:ClearFocus()
247 | self.frame:SetScript("OnShow", nil)
248 | end,
249 |
250 | ["SetFocus"] = function(self)
251 | self.editBox:SetFocus()
252 | if not self.frame:IsShown() then
253 | self.frame:SetScript("OnShow", OnShowFocus)
254 | end
255 | end,
256 |
257 | ["HighlightText"] = function(self, from, to)
258 | self.editBox:HighlightText(from, to)
259 | end,
260 |
261 | ["GetCursorPosition"] = function(self)
262 | return self.editBox:GetCursorPosition()
263 | end,
264 |
265 | ["SetCursorPosition"] = function(self, ...)
266 | return self.editBox:SetCursorPosition(...)
267 | end,
268 | }
269 |
270 | --[[-----------------------------------------------------------------------------
271 | Constructor
272 | -------------------------------------------------------------------------------]]
273 | local backdrop = {
274 | bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
275 | edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
276 | insets = { left = 4, right = 3, top = 4, bottom = 3 }
277 | }
278 |
279 | local function Constructor()
280 | local frame = CreateFrame("Frame", nil, UIParent)
281 | frame:Hide()
282 |
283 | local widgetNum = AceGUI:GetNextWidgetNum(Type)
284 |
285 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
286 | label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
287 | label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
288 | label:SetJustifyH("LEFT")
289 | label:SetText(ACCEPT)
290 | label:SetHeight(10)
291 |
292 | local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate")
293 | button:SetPoint("BOTTOMLEFT", 0, 4)
294 | button:SetHeight(22)
295 | button:SetWidth(label:GetStringWidth() + 24)
296 | button:SetText(ACCEPT)
297 | button:SetScript("OnClick", OnClick)
298 | button:Disable()
299 |
300 | local text = button:GetFontString()
301 | text:ClearAllPoints()
302 | text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
303 | text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
304 | text:SetJustifyV("MIDDLE")
305 |
306 | local scrollBG = CreateFrame("Frame", nil, frame, "BackdropTemplate")
307 | scrollBG:SetBackdrop(backdrop)
308 | scrollBG:SetBackdropColor(0, 0, 0)
309 | scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
310 |
311 | local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
312 |
313 | local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
314 | scrollBar:ClearAllPoints()
315 | scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
316 | scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
317 | scrollBar:SetPoint("RIGHT", frame, "RIGHT")
318 |
319 | scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
320 | scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
321 |
322 | scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
323 | scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
324 | scrollFrame:SetScript("OnEnter", OnEnter)
325 | scrollFrame:SetScript("OnLeave", OnLeave)
326 | scrollFrame:SetScript("OnMouseUp", OnMouseUp)
327 | scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
328 | scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
329 | scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
330 | scrollFrame:HookScript("OnScrollRangeChanged", OnScrollRangeChanged)
331 |
332 | local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
333 | editBox:SetAllPoints()
334 | editBox:SetFontObject(ChatFontNormal)
335 | editBox:SetMultiLine(true)
336 | editBox:EnableMouse(true)
337 | editBox:SetAutoFocus(false)
338 | editBox:SetCountInvisibleLetters(false)
339 | editBox:SetScript("OnCursorChanged", OnCursorChanged)
340 | editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
341 | editBox:SetScript("OnEnter", OnEnter)
342 | editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
343 | editBox:SetScript("OnLeave", OnLeave)
344 | editBox:SetScript("OnMouseDown", OnReceiveDrag)
345 | editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
346 | editBox:SetScript("OnTextChanged", OnTextChanged)
347 | editBox:SetScript("OnTextSet", OnTextSet)
348 | editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
349 |
350 |
351 | scrollFrame:SetScrollChild(editBox)
352 |
353 | local widget = {
354 | button = button,
355 | editBox = editBox,
356 | frame = frame,
357 | label = label,
358 | labelHeight = 10,
359 | numlines = 4,
360 | scrollBar = scrollBar,
361 | scrollBG = scrollBG,
362 | scrollFrame = scrollFrame,
363 | type = Type
364 | }
365 | for method, func in pairs(methods) do
366 | widget[method] = func
367 | end
368 | button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
369 |
370 | return AceGUI:RegisterAsWidget(widget)
371 | end
372 |
373 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
374 |
--------------------------------------------------------------------------------
/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Slider Widget
3 | Graphical Slider, like, for Range values.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Slider", 23
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local min, max, floor = math.min, math.max, math.floor
11 | local tonumber, pairs = tonumber, pairs
12 |
13 | -- WoW APIs
14 | local PlaySound = PlaySound
15 | local CreateFrame, UIParent = CreateFrame, UIParent
16 |
17 | --[[-----------------------------------------------------------------------------
18 | Support functions
19 | -------------------------------------------------------------------------------]]
20 | local function UpdateText(self)
21 | local value = self.value or 0
22 | if self.ispercent then
23 | self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
24 | else
25 | self.editbox:SetText(floor(value * 100 + 0.5) / 100)
26 | end
27 | end
28 |
29 | local function UpdateLabels(self)
30 | local min_value, max_value = (self.min or 0), (self.max or 100)
31 | if self.ispercent then
32 | self.lowtext:SetFormattedText("%s%%", (min_value * 100))
33 | self.hightext:SetFormattedText("%s%%", (max_value * 100))
34 | else
35 | self.lowtext:SetText(min_value)
36 | self.hightext:SetText(max_value)
37 | end
38 | end
39 |
40 | --[[-----------------------------------------------------------------------------
41 | Scripts
42 | -------------------------------------------------------------------------------]]
43 | local function Control_OnEnter(frame)
44 | frame.obj:Fire("OnEnter")
45 | end
46 |
47 | local function Control_OnLeave(frame)
48 | frame.obj:Fire("OnLeave")
49 | end
50 |
51 | local function Frame_OnMouseDown(frame)
52 | frame.obj.slider:EnableMouseWheel(true)
53 | AceGUI:ClearFocus()
54 | end
55 |
56 | local function Slider_OnValueChanged(frame, newvalue)
57 | local self = frame.obj
58 | if not frame.setup then
59 | if self.step and self.step > 0 then
60 | local min_value = self.min or 0
61 | newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
62 | end
63 | if newvalue ~= self.value and not self.disabled then
64 | self.value = newvalue
65 | self:Fire("OnValueChanged", newvalue)
66 | end
67 | if self.value then
68 | UpdateText(self)
69 | end
70 | end
71 | end
72 |
73 | local function Slider_OnMouseUp(frame)
74 | local self = frame.obj
75 | self:Fire("OnMouseUp", self.value)
76 | end
77 |
78 | local function Slider_OnMouseWheel(frame, v)
79 | local self = frame.obj
80 | if not self.disabled then
81 | local value = self.value
82 | if v > 0 then
83 | value = min(value + (self.step or 1), self.max)
84 | else
85 | value = max(value - (self.step or 1), self.min)
86 | end
87 | self.slider:SetValue(value)
88 | end
89 | end
90 |
91 | local function EditBox_OnEscapePressed(frame)
92 | frame:ClearFocus()
93 | end
94 |
95 | local function EditBox_OnEnterPressed(frame)
96 | local self = frame.obj
97 | local value = frame:GetText()
98 | if self.ispercent then
99 | value = value:gsub('%%', '')
100 | value = tonumber(value) / 100
101 | else
102 | value = tonumber(value)
103 | end
104 |
105 | if value then
106 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
107 | self.slider:SetValue(value)
108 | self:Fire("OnMouseUp", value)
109 | end
110 | end
111 |
112 | local function EditBox_OnEnter(frame)
113 | frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
114 | end
115 |
116 | local function EditBox_OnLeave(frame)
117 | frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
118 | end
119 |
120 | --[[-----------------------------------------------------------------------------
121 | Methods
122 | -------------------------------------------------------------------------------]]
123 | local methods = {
124 | ["OnAcquire"] = function(self)
125 | self:SetWidth(200)
126 | self:SetHeight(44)
127 | self:SetDisabled(false)
128 | self:SetIsPercent(nil)
129 | self:SetSliderValues(0,100,1)
130 | self:SetValue(0)
131 | self.slider:EnableMouseWheel(false)
132 | end,
133 |
134 | -- ["OnRelease"] = nil,
135 |
136 | ["SetDisabled"] = function(self, disabled)
137 | self.disabled = disabled
138 | if disabled then
139 | self.slider:EnableMouse(false)
140 | self.label:SetTextColor(.5, .5, .5)
141 | self.hightext:SetTextColor(.5, .5, .5)
142 | self.lowtext:SetTextColor(.5, .5, .5)
143 | --self.valuetext:SetTextColor(.5, .5, .5)
144 | self.editbox:SetTextColor(.5, .5, .5)
145 | self.editbox:EnableMouse(false)
146 | self.editbox:ClearFocus()
147 | else
148 | self.slider:EnableMouse(true)
149 | self.label:SetTextColor(1, .82, 0)
150 | self.hightext:SetTextColor(1, 1, 1)
151 | self.lowtext:SetTextColor(1, 1, 1)
152 | --self.valuetext:SetTextColor(1, 1, 1)
153 | self.editbox:SetTextColor(1, 1, 1)
154 | self.editbox:EnableMouse(true)
155 | end
156 | end,
157 |
158 | ["SetValue"] = function(self, value)
159 | self.slider.setup = true
160 | self.slider:SetValue(value)
161 | self.value = value
162 | UpdateText(self)
163 | self.slider.setup = nil
164 | end,
165 |
166 | ["GetValue"] = function(self)
167 | return self.value
168 | end,
169 |
170 | ["SetLabel"] = function(self, text)
171 | self.label:SetText(text)
172 | end,
173 |
174 | ["SetSliderValues"] = function(self, min_value, max_value, step)
175 | local frame = self.slider
176 | frame.setup = true
177 | self.min = min_value
178 | self.max = max_value
179 | self.step = step
180 | frame:SetMinMaxValues(min_value or 0,max_value or 100)
181 | UpdateLabels(self)
182 | frame:SetValueStep(step or 1)
183 | if self.value then
184 | frame:SetValue(self.value)
185 | end
186 | frame.setup = nil
187 | end,
188 |
189 | ["SetIsPercent"] = function(self, value)
190 | self.ispercent = value
191 | UpdateLabels(self)
192 | UpdateText(self)
193 | end
194 | }
195 |
196 | --[[-----------------------------------------------------------------------------
197 | Constructor
198 | -------------------------------------------------------------------------------]]
199 | local SliderBackdrop = {
200 | bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
201 | edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
202 | tile = true, tileSize = 8, edgeSize = 8,
203 | insets = { left = 3, right = 3, top = 6, bottom = 6 }
204 | }
205 |
206 | local ManualBackdrop = {
207 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
208 | edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
209 | tile = true, edgeSize = 1, tileSize = 5,
210 | }
211 |
212 | local function Constructor()
213 | local frame = CreateFrame("Frame", nil, UIParent)
214 |
215 | frame:EnableMouse(true)
216 | frame:SetScript("OnMouseDown", Frame_OnMouseDown)
217 |
218 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
219 | label:SetPoint("TOPLEFT")
220 | label:SetPoint("TOPRIGHT")
221 | label:SetJustifyH("CENTER")
222 | label:SetHeight(15)
223 |
224 | local slider = CreateFrame("Slider", nil, frame, "BackdropTemplate")
225 | slider:SetOrientation("HORIZONTAL")
226 | slider:SetHeight(15)
227 | slider:SetHitRectInsets(0, 0, -10, 0)
228 | slider:SetBackdrop(SliderBackdrop)
229 | slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
230 | slider:SetPoint("TOP", label, "BOTTOM")
231 | slider:SetPoint("LEFT", 3, 0)
232 | slider:SetPoint("RIGHT", -3, 0)
233 | slider:SetValue(0)
234 | slider:SetScript("OnValueChanged",Slider_OnValueChanged)
235 | slider:SetScript("OnEnter", Control_OnEnter)
236 | slider:SetScript("OnLeave", Control_OnLeave)
237 | slider:SetScript("OnMouseUp", Slider_OnMouseUp)
238 | slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
239 |
240 | local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
241 | lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
242 |
243 | local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
244 | hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
245 |
246 | local editbox = CreateFrame("EditBox", nil, frame, "BackdropTemplate")
247 | editbox:SetAutoFocus(false)
248 | editbox:SetFontObject(GameFontHighlightSmall)
249 | editbox:SetPoint("TOP", slider, "BOTTOM")
250 | editbox:SetHeight(14)
251 | editbox:SetWidth(70)
252 | editbox:SetJustifyH("CENTER")
253 | editbox:EnableMouse(true)
254 | editbox:SetBackdrop(ManualBackdrop)
255 | editbox:SetBackdropColor(0, 0, 0, 0.5)
256 | editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
257 | editbox:SetScript("OnEnter", EditBox_OnEnter)
258 | editbox:SetScript("OnLeave", EditBox_OnLeave)
259 | editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
260 | editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
261 |
262 | local widget = {
263 | label = label,
264 | slider = slider,
265 | lowtext = lowtext,
266 | hightext = hightext,
267 | editbox = editbox,
268 | alignoffset = 25,
269 | frame = frame,
270 | type = Type
271 | }
272 | for method, func in pairs(methods) do
273 | widget[method] = func
274 | end
275 | slider.obj, editbox.obj = widget, widget
276 |
277 | return AceGUI:RegisterAsWidget(widget)
278 | end
279 |
280 | AceGUI:RegisterWidgetType(Type,Constructor,Version)
281 |
--------------------------------------------------------------------------------
/Libs/AceTimer-3.0/AceTimer-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceTimer-3.0** provides a central facility for registering timers.
2 | -- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
3 | -- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
4 | -- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
5 | -- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API
6 | -- restricts us to.
7 | --
8 | -- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
9 | -- need to cancel the timer you just registered.
10 | --
11 | -- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
12 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
13 | -- and can be accessed directly, without having to explicitly call AceTimer itself.\\
14 | -- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
15 | -- make into AceTimer.
16 | -- @class file
17 | -- @name AceTimer-3.0
18 | -- @release $Id: AceTimer-3.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $
19 |
20 | local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes
21 | local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
22 |
23 | if not AceTimer then return end -- No upgrade needed
24 | AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
25 | local activeTimers = AceTimer.activeTimers -- Upvalue our private data
26 |
27 | -- Lua APIs
28 | local type, unpack, next, error, select = type, unpack, next, error, select
29 | -- WoW APIs
30 | local GetTime, C_TimerAfter = GetTime, C_Timer.After
31 |
32 | local function new(self, loop, func, delay, ...)
33 | if delay < 0.01 then
34 | delay = 0.01 -- Restrict to the lowest time that the C_Timer API allows us
35 | end
36 |
37 | local timer = {
38 | object = self,
39 | func = func,
40 | looping = loop,
41 | argsCount = select("#", ...),
42 | delay = delay,
43 | ends = GetTime() + delay,
44 | ...
45 | }
46 |
47 | activeTimers[timer] = timer
48 |
49 | -- Create new timer closure to wrap the "timer" object
50 | timer.callback = function()
51 | if not timer.cancelled then
52 | if type(timer.func) == "string" then
53 | -- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
54 | -- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
55 | timer.object[timer.func](timer.object, unpack(timer, 1, timer.argsCount))
56 | else
57 | timer.func(unpack(timer, 1, timer.argsCount))
58 | end
59 |
60 | if timer.looping and not timer.cancelled then
61 | -- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
62 | -- due to fps differences
63 | local time = GetTime()
64 | local ndelay = timer.delay - (time - timer.ends)
65 | -- Ensure the delay doesn't go below the threshold
66 | if ndelay < 0.01 then ndelay = 0.01 end
67 | C_TimerAfter(ndelay, timer.callback)
68 | timer.ends = time + ndelay
69 | else
70 | activeTimers[timer.handle or timer] = nil
71 | end
72 | end
73 | end
74 |
75 | C_TimerAfter(delay, timer.callback)
76 | return timer
77 | end
78 |
79 | --- Schedule a new one-shot timer.
80 | -- The timer will fire once in `delay` seconds, unless canceled before.
81 | -- @param callback Callback function for the timer pulse (funcref or method name).
82 | -- @param delay Delay for the timer, in seconds.
83 | -- @param ... An optional, unlimited amount of arguments to pass to the callback function.
84 | -- @usage
85 | -- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
86 | --
87 | -- function MyAddOn:OnEnable()
88 | -- self:ScheduleTimer("TimerFeedback", 5)
89 | -- end
90 | --
91 | -- function MyAddOn:TimerFeedback()
92 | -- print("5 seconds passed")
93 | -- end
94 | function AceTimer:ScheduleTimer(func, delay, ...)
95 | if not func or not delay then
96 | error(MAJOR..": ScheduleTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
97 | end
98 | if type(func) == "string" then
99 | if type(self) ~= "table" then
100 | error(MAJOR..": ScheduleTimer(callback, delay, args...): 'self' - must be a table.", 2)
101 | elseif not self[func] then
102 | error(MAJOR..": ScheduleTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
103 | end
104 | end
105 | return new(self, nil, func, delay, ...)
106 | end
107 |
108 | --- Schedule a repeating timer.
109 | -- The timer will fire every `delay` seconds, until canceled.
110 | -- @param callback Callback function for the timer pulse (funcref or method name).
111 | -- @param delay Delay for the timer, in seconds.
112 | -- @param ... An optional, unlimited amount of arguments to pass to the callback function.
113 | -- @usage
114 | -- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
115 | --
116 | -- function MyAddOn:OnEnable()
117 | -- self.timerCount = 0
118 | -- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
119 | -- end
120 | --
121 | -- function MyAddOn:TimerFeedback()
122 | -- self.timerCount = self.timerCount + 1
123 | -- print(("%d seconds passed"):format(5 * self.timerCount))
124 | -- -- run 30 seconds in total
125 | -- if self.timerCount == 6 then
126 | -- self:CancelTimer(self.testTimer)
127 | -- end
128 | -- end
129 | function AceTimer:ScheduleRepeatingTimer(func, delay, ...)
130 | if not func or not delay then
131 | error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
132 | end
133 | if type(func) == "string" then
134 | if type(self) ~= "table" then
135 | error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'self' - must be a table.", 2)
136 | elseif not self[func] then
137 | error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
138 | end
139 | end
140 | return new(self, true, func, delay, ...)
141 | end
142 |
143 | --- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
144 | -- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
145 | -- and the timer has not fired yet or was canceled before.
146 | -- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
147 | function AceTimer:CancelTimer(id)
148 | local timer = activeTimers[id]
149 |
150 | if not timer then
151 | return false
152 | else
153 | timer.cancelled = true
154 | activeTimers[id] = nil
155 | return true
156 | end
157 | end
158 |
159 | --- Cancels all timers registered to the current addon object ('self')
160 | function AceTimer:CancelAllTimers()
161 | for k,v in next, activeTimers do
162 | if v.object == self then
163 | AceTimer.CancelTimer(self, k)
164 | end
165 | end
166 | end
167 |
168 | --- Returns the time left for a timer with the given id, registered by the current addon object ('self').
169 | -- This function will return 0 when the id is invalid.
170 | -- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
171 | -- @return The time left on the timer.
172 | function AceTimer:TimeLeft(id)
173 | local timer = activeTimers[id]
174 | if not timer then
175 | return 0
176 | else
177 | return timer.ends - GetTime()
178 | end
179 | end
180 |
181 |
182 | -- ---------------------------------------------------------------------
183 | -- Upgrading
184 |
185 | -- Upgrade from old hash-bucket based timers to C_Timer.After timers.
186 | if oldminor and oldminor < 10 then
187 | -- disable old timer logic
188 | AceTimer.frame:SetScript("OnUpdate", nil)
189 | AceTimer.frame:SetScript("OnEvent", nil)
190 | AceTimer.frame:UnregisterAllEvents()
191 | -- convert timers
192 | for object,timers in next, AceTimer.selfs do
193 | for handle,timer in next, timers do
194 | if type(timer) == "table" and timer.callback then
195 | local newTimer
196 | if timer.delay then
197 | newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.callback, timer.delay, timer.arg)
198 | else
199 | newTimer = AceTimer.ScheduleTimer(timer.object, timer.callback, timer.when - GetTime(), timer.arg)
200 | end
201 | -- Use the old handle for old timers
202 | activeTimers[newTimer] = nil
203 | activeTimers[handle] = newTimer
204 | newTimer.handle = handle
205 | end
206 | end
207 | end
208 | AceTimer.selfs = nil
209 | AceTimer.hash = nil
210 | AceTimer.debug = nil
211 | elseif oldminor and oldminor < 17 then
212 | -- Upgrade from old animation based timers to C_Timer.After timers.
213 | AceTimer.inactiveTimers = nil
214 | AceTimer.frame = nil
215 | local oldTimers = AceTimer.activeTimers
216 | -- Clear old timer table and update upvalue
217 | AceTimer.activeTimers = {}
218 | activeTimers = AceTimer.activeTimers
219 | for handle, timer in next, oldTimers do
220 | local newTimer
221 | -- Stop the old timer animation
222 | local duration, elapsed = timer:GetDuration(), timer:GetElapsed()
223 | timer:GetParent():Stop()
224 | if timer.looping then
225 | newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.func, duration, unpack(timer.args, 1, timer.argsCount))
226 | else
227 | newTimer = AceTimer.ScheduleTimer(timer.object, timer.func, duration - elapsed, unpack(timer.args, 1, timer.argsCount))
228 | end
229 | -- Use the old handle for old timers
230 | activeTimers[newTimer] = nil
231 | activeTimers[handle] = newTimer
232 | newTimer.handle = handle
233 | end
234 |
235 | -- Migrate transitional handles
236 | if oldminor < 13 and AceTimer.hashCompatTable then
237 | for handle, id in next, AceTimer.hashCompatTable do
238 | local t = activeTimers[id]
239 | if t then
240 | activeTimers[id] = nil
241 | activeTimers[handle] = t
242 | t.handle = handle
243 | end
244 | end
245 | AceTimer.hashCompatTable = nil
246 | end
247 | end
248 |
249 | -- ---------------------------------------------------------------------
250 | -- Embed handling
251 |
252 | AceTimer.embeds = AceTimer.embeds or {}
253 |
254 | local mixins = {
255 | "ScheduleTimer", "ScheduleRepeatingTimer",
256 | "CancelTimer", "CancelAllTimers",
257 | "TimeLeft"
258 | }
259 |
260 | function AceTimer:Embed(target)
261 | AceTimer.embeds[target] = true
262 | for _,v in next, mixins do
263 | target[v] = AceTimer[v]
264 | end
265 | return target
266 | end
267 |
268 | -- AceTimer:OnEmbedDisable(target)
269 | -- target (object) - target object that AceTimer is embedded in.
270 | --
271 | -- cancel all timers registered for the object
272 | function AceTimer:OnEmbedDisable(target)
273 | target:CancelAllTimers()
274 | end
275 |
276 | for addon in next, AceTimer.embeds do
277 | AceTimer:Embed(addon)
278 | end
279 |
--------------------------------------------------------------------------------
/Libs/AceTimer-3.0/AceTimer-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:
--------------------------------------------------------------------------------
1 | --[[ $Id: CallbackHandler-1.0.lua 1298 2022-12-12 15:10:10Z nevcairiel $ ]]
2 | local MAJOR, MINOR = "CallbackHandler-1.0", 8
3 | local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
4 |
5 | if not CallbackHandler then return end -- No upgrade needed
6 |
7 | local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
8 |
9 | -- Lua APIs
10 | local securecallfunction, error = securecallfunction, error
11 | local setmetatable, rawget = setmetatable, rawget
12 | local next, select, pairs, type, tostring = next, select, pairs, type, tostring
13 |
14 |
15 | local function Dispatch(handlers, ...)
16 | local index, method = next(handlers)
17 | if not method then return end
18 | repeat
19 | securecallfunction(method, ...)
20 | index, method = next(handlers, index)
21 | until not method
22 | end
23 |
24 | --------------------------------------------------------------------------
25 | -- CallbackHandler:New
26 | --
27 | -- target - target object to embed public APIs in
28 | -- RegisterName - name of the callback registration API, default "RegisterCallback"
29 | -- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
30 | -- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
31 |
32 | function CallbackHandler.New(_self, target, RegisterName, UnregisterName, UnregisterAllName)
33 |
34 | RegisterName = RegisterName or "RegisterCallback"
35 | UnregisterName = UnregisterName or "UnregisterCallback"
36 | if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
37 | UnregisterAllName = "UnregisterAllCallbacks"
38 | end
39 |
40 | -- we declare all objects and exported APIs inside this closure to quickly gain access
41 | -- to e.g. function names, the "target" parameter, etc
42 |
43 |
44 | -- Create the registry object
45 | local events = setmetatable({}, meta)
46 | local registry = { recurse=0, events=events }
47 |
48 | -- registry:Fire() - fires the given event/message into the registry
49 | function registry:Fire(eventname, ...)
50 | if not rawget(events, eventname) or not next(events[eventname]) then return end
51 | local oldrecurse = registry.recurse
52 | registry.recurse = oldrecurse + 1
53 |
54 | Dispatch(events[eventname], eventname, ...)
55 |
56 | registry.recurse = oldrecurse
57 |
58 | if registry.insertQueue and oldrecurse==0 then
59 | -- Something in one of our callbacks wanted to register more callbacks; they got queued
60 | for event,callbacks in pairs(registry.insertQueue) do
61 | 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.
62 | for object,func in pairs(callbacks) do
63 | events[event][object] = func
64 | -- fire OnUsed callback?
65 | if first and registry.OnUsed then
66 | registry.OnUsed(registry, target, event)
67 | first = nil
68 | end
69 | end
70 | end
71 | registry.insertQueue = nil
72 | end
73 | end
74 |
75 | -- Registration of a callback, handles:
76 | -- self["method"], leads to self["method"](self, ...)
77 | -- self with function ref, leads to functionref(...)
78 | -- "addonId" (instead of self) with function ref, leads to functionref(...)
79 | -- all with an optional arg, which, if present, gets passed as first argument (after self if present)
80 | target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
81 | if type(eventname) ~= "string" then
82 | error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
83 | end
84 |
85 | method = method or eventname
86 |
87 | 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.
88 |
89 | if type(method) ~= "string" and type(method) ~= "function" then
90 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
91 | end
92 |
93 | local regfunc
94 |
95 | if type(method) == "string" then
96 | -- self["method"] calling style
97 | if type(self) ~= "table" then
98 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
99 | elseif self==target then
100 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
101 | elseif type(self[method]) ~= "function" then
102 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
103 | end
104 |
105 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
106 | local arg=select(1,...)
107 | regfunc = function(...) self[method](self,arg,...) end
108 | else
109 | regfunc = function(...) self[method](self,...) end
110 | end
111 | else
112 | -- function ref with self=object or self="addonId" or self=thread
113 | if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
114 | error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
115 | end
116 |
117 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
118 | local arg=select(1,...)
119 | regfunc = function(...) method(arg,...) end
120 | else
121 | regfunc = method
122 | end
123 | end
124 |
125 |
126 | if events[eventname][self] or registry.recurse<1 then
127 | -- if registry.recurse<1 then
128 | -- we're overwriting an existing entry, or not currently recursing. just set it.
129 | events[eventname][self] = regfunc
130 | -- fire OnUsed callback?
131 | if registry.OnUsed and first then
132 | registry.OnUsed(registry, target, eventname)
133 | end
134 | else
135 | -- we're currently processing a callback in this registry, so delay the registration of this new entry!
136 | -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
137 | registry.insertQueue = registry.insertQueue or setmetatable({},meta)
138 | registry.insertQueue[eventname][self] = regfunc
139 | end
140 | end
141 |
142 | -- Unregister a callback
143 | target[UnregisterName] = function(self, eventname)
144 | if not self or self==target then
145 | error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
146 | end
147 | if type(eventname) ~= "string" then
148 | error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
149 | end
150 | if rawget(events, eventname) and events[eventname][self] then
151 | events[eventname][self] = nil
152 | -- Fire OnUnused callback?
153 | if registry.OnUnused and not next(events[eventname]) then
154 | registry.OnUnused(registry, target, eventname)
155 | end
156 | end
157 | if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
158 | registry.insertQueue[eventname][self] = nil
159 | end
160 | end
161 |
162 | -- OPTIONAL: Unregister all callbacks for given selfs/addonIds
163 | if UnregisterAllName then
164 | target[UnregisterAllName] = function(...)
165 | if select("#",...)<1 then
166 | error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
167 | end
168 | if select("#",...)==1 and ...==target then
169 | error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
170 | end
171 |
172 |
173 | for i=1,select("#",...) do
174 | local self = select(i,...)
175 | if registry.insertQueue then
176 | for eventname, callbacks in pairs(registry.insertQueue) do
177 | if callbacks[self] then
178 | callbacks[self] = nil
179 | end
180 | end
181 | end
182 | for eventname, callbacks in pairs(events) do
183 | if callbacks[self] then
184 | callbacks[self] = nil
185 | -- Fire OnUnused callback?
186 | if registry.OnUnused and not next(callbacks) then
187 | registry.OnUnused(registry, target, eventname)
188 | end
189 | end
190 | end
191 | end
192 | end
193 | end
194 |
195 | return registry
196 | end
197 |
198 |
199 | -- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
200 | -- try to upgrade old implicit embeds since the system is selfcontained and
201 | -- relies on closures to work.
202 |
203 |
--------------------------------------------------------------------------------
/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Libs/LibDBIcon-1.0/lib.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua:
--------------------------------------------------------------------------------
1 | assert(LibStub, "LibDataBroker-1.1 requires LibStub")
2 | assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
3 |
4 | local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
5 | if not lib then return end
6 | oldminor = oldminor or 0
7 |
8 |
9 | lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
10 | lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
11 | local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
12 |
13 | if oldminor < 2 then
14 | lib.domt = {
15 | __metatable = "access denied",
16 | __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
17 | }
18 | end
19 |
20 | if oldminor < 3 then
21 | lib.domt.__newindex = function(self, key, value)
22 | if not attributestorage[self] then attributestorage[self] = {} end
23 | if attributestorage[self][key] == value then return end
24 | attributestorage[self][key] = value
25 | local name = namestorage[self]
26 | if not name then return end
27 | callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
28 | callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
29 | callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
30 | callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
31 | end
32 | end
33 |
34 | if oldminor < 2 then
35 | function lib:NewDataObject(name, dataobj)
36 | if self.proxystorage[name] then return end
37 |
38 | if dataobj then
39 | assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
40 | self.attributestorage[dataobj] = {}
41 | for i,v in pairs(dataobj) do
42 | self.attributestorage[dataobj][i] = v
43 | dataobj[i] = nil
44 | end
45 | end
46 | dataobj = setmetatable(dataobj or {}, self.domt)
47 | self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
48 | self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
49 | return dataobj
50 | end
51 | end
52 |
53 | if oldminor < 1 then
54 | function lib:DataObjectIterator()
55 | return pairs(self.proxystorage)
56 | end
57 |
58 | function lib:GetDataObjectByName(dataobjectname)
59 | return self.proxystorage[dataobjectname]
60 | end
61 |
62 | function lib:GetNameByDataObject(dataobject)
63 | return self.namestorage[dataobject]
64 | end
65 | end
66 |
67 | if oldminor < 4 then
68 | local next = pairs(attributestorage)
69 | function lib:pairs(dataobject_or_name)
70 | local t = type(dataobject_or_name)
71 | assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
72 |
73 | local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
74 | assert(attributestorage[dataobj], "Data object not found")
75 |
76 | return next, attributestorage[dataobj], nil
77 | end
78 |
79 | local ipairs_iter = ipairs(attributestorage)
80 | function lib:ipairs(dataobject_or_name)
81 | local t = type(dataobject_or_name)
82 | assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
83 |
84 | local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
85 | assert(attributestorage[dataobj], "Data object not found")
86 |
87 | return ipairs_iter, attributestorage[dataobj], 0
88 | end
89 | end
--------------------------------------------------------------------------------
/Libs/LibStub/LibStub.lua:
--------------------------------------------------------------------------------
1 | -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
2 | -- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
3 | local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
4 | local LibStub = _G[LIBSTUB_MAJOR]
5 |
6 | if not LibStub or LibStub.minor < LIBSTUB_MINOR then
7 | LibStub = LibStub or {libs = {}, minors = {} }
8 | _G[LIBSTUB_MAJOR] = LibStub
9 | LibStub.minor = LIBSTUB_MINOR
10 |
11 | function LibStub:NewLibrary(major, minor)
12 | assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
13 | minor = assert(tonumber(string.match(minor, "%d+")), "Minor version must either be a number or contain a number.")
14 |
15 | local oldminor = self.minors[major]
16 | if oldminor and oldminor >= minor then return nil end
17 | self.minors[major], self.libs[major] = minor, self.libs[major] or {}
18 | return self.libs[major], oldminor
19 | end
20 |
21 | function LibStub:GetLibrary(major, silent)
22 | if not self.libs[major] and not silent then
23 | error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
24 | end
25 | return self.libs[major], self.minors[major]
26 | end
27 |
28 | function LibStub:IterateLibraries() return pairs(self.libs) end
29 | setmetatable(LibStub, { __call = LibStub.GetLibrary })
30 | end
31 |
--------------------------------------------------------------------------------
/Media/Icon.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon.blp
--------------------------------------------------------------------------------
/Media/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon.png
--------------------------------------------------------------------------------
/Media/Icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/Media/Icon_Characters.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Characters.blp
--------------------------------------------------------------------------------
/Media/Icon_Characters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Characters.png
--------------------------------------------------------------------------------
/Media/Icon_Checklist.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Checklist.blp
--------------------------------------------------------------------------------
/Media/Icon_Checklist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Checklist.png
--------------------------------------------------------------------------------
/Media/Icon_Close.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Close.blp
--------------------------------------------------------------------------------
/Media/Icon_Close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Close.png
--------------------------------------------------------------------------------
/Media/Icon_Columns.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Columns.blp
--------------------------------------------------------------------------------
/Media/Icon_Columns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Columns.png
--------------------------------------------------------------------------------
/Media/Icon_Settings.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Settings.blp
--------------------------------------------------------------------------------
/Media/Icon_Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Settings.png
--------------------------------------------------------------------------------
/Media/Icon_Toggle.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Toggle.blp
--------------------------------------------------------------------------------
/Media/Icon_Toggle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Icon_Toggle.png
--------------------------------------------------------------------------------
/Media/Logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Logo.jpg
--------------------------------------------------------------------------------
/Media/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Logo.png
--------------------------------------------------------------------------------
/Media/Logo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Logo.psd
--------------------------------------------------------------------------------
/Media/Screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot1.png
--------------------------------------------------------------------------------
/Media/Screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot2.png
--------------------------------------------------------------------------------
/Media/Screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot3.png
--------------------------------------------------------------------------------
/Media/Screenshot4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot4.png
--------------------------------------------------------------------------------
/Media/Screenshot5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot5.png
--------------------------------------------------------------------------------
/Media/Screenshot6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/Screenshot6.png
--------------------------------------------------------------------------------
/Media/ScreenshotOld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DennisRas/WeeklyKnowledge/0d29072e2a6551d3343f1317d38dfaf333b518c9/Media/ScreenshotOld.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | WeeklyKnowledge offers an easy-to-read grid overview of your profession knowledge progress on all your characters. Quickly identify which points you've successfully gathered and where you might need to focus your efforts. Never lose track of your knowledge points with this addon.
2 |
3 | With WeeklyKnowledge, your WoW experience becomes more efficient.
4 |
5 | Download WeeklyKnowledge today and take control of your gaming experience like never before!
6 |
7 | ## Slash Commands
8 |
9 | - **/weeklyknowledge** - toggles the main window
10 | - **/weeklyknowledge minimap** - toggles the minimap icon
11 |
12 | You can also use the short command **/wk**
13 |
14 | ## Feedback
15 |
16 | Your feedback is invaluable and instrumental in making WeeklyKnowledge the best it can be.
17 | If you come across any bugs or have suggestions for improvements, please don't hesitate to reach out.
18 |
--------------------------------------------------------------------------------
/Types.lua:
--------------------------------------------------------------------------------
1 | ---@class WK_DefaultGlobal
2 | ---@field DBVersion integer?
3 | ---@field weeklyReset integer?
4 | ---@field minimap {minimapPos: number, hide: boolean, lock: boolean }
5 | ---@field characters table
6 | ---@field main WK_DefaultGlobalMain
7 | ---@field checklist WK_DefaultGlobalhecklist
8 |
9 | ---@class WK_DefaultGlobalMain
10 | ---@field hiddenColumns table
11 | ---@field windowScale integer
12 | ---@field windowBackgroundColor {r: number, g: number, b: number, a: number}
13 | ---@field windowBorder boolean Show the border?
14 | ---@field fontSize integer?
15 | ---@field checklistHelpTipClosed boolean?
16 |
17 | ---@class WK_DefaultGlobalhecklist
18 | ---@field hiddenColumns table
19 | ---@field windowScale integer
20 | ---@field windowBackgroundColor {r: number, g: number, b: number, a: number}
21 | ---@field windowBorder boolean Show the border?
22 | ---@field windowTitlebar boolean
23 | ---@field fontSize integer?
24 | ---@field open boolean
25 | ---@field hideCompletedObjectives boolean
26 | ---@field hideInCombat boolean
27 | ---@field hideInDungeons boolean
28 | ---@field hideTable boolean
29 | ---@field hideTableHeader boolean
30 | ---@field hideUniqueObjectives boolean
31 | ---@field hideUniqueVendorObjectives boolean
32 | ---@field hideCatchUpObjectives boolean
33 |
34 | ---@class WK_Character
35 | ---@field GUID string|WOWGUID
36 | ---@field enabled boolean
37 | ---@field name string
38 | ---@field realmName string
39 | ---@field level integer
40 | ---@field factionEnglish string
41 | ---@field factionName string
42 | ---@field raceID integer
43 | ---@field raceEnglish string
44 | ---@field raceName string
45 | ---@field classID integer
46 | ---@field classFile ClassFile?
47 | ---@field className string
48 | ---@field lastUpdate number
49 | ---@field professions WK_CharacterProfession[]
50 | ---@field completed table
51 |
52 | ---@class WK_CharacterProfession
53 | ---@field enabled boolean
54 | ---@field skillLineID integer
55 | ---@field level integer
56 | ---@field maxLevel integer
57 | ---@field knowledgeLevel integer
58 | ---@field knowledgeMaxLevel integer
59 | ---@field knowledgeUnspent integer
60 | ---@field specializations table
61 | ---@field catchUpCurrencyInfo CurrencyInfo?
62 |
63 | ---@class WK_ObjectiveType
64 | ---@field id Enum.WK_Objectives
65 | ---@field name string
66 | ---@field description string
67 | ---@field type "item" | "quest"
68 | ---@field repeatable "No" | "Weekly" | "Monthly"
69 |
70 | ---@class WK_Profession
71 | ---@field name string
72 | ---@field skillLineID integer Profession ID
73 | ---@field skillLineVariantID integer Profession Expansion Variant ID
74 | ---@field spellID integer Learned Profession Spell ID
75 | ---@field catchUpCurrencyID integer
76 | ---@field catchUpWeeklyCap integer
77 | ---@field catchUpItemID integer
78 |
79 | ---@class WK_Objective
80 | ---@field professionID integer
81 | ---@field typeID Enum.WK_Objectives
82 | ---@field quests integer[]
83 | ---@field itemID integer?
84 | ---@field points integer
85 | ---@field limit integer?
86 |
87 | ---@class WK_DataCache
88 | ---@field isDarkmoonOpen boolean
89 | ---@field inCombat boolean
90 | ---@field items table
91 | ---@field mapInfo table
92 |
93 | ---@class WK_DataColumn
94 | ---@field name string
95 | ---@field width integer
96 | ---@field align "LEFT" | "CENTER" | "RIGHT" | nil
97 | ---@field onEnter function?
98 | ---@field onLeave function?
99 | ---@field cell fun(character: WK_Character, characterProfession: WK_CharacterProfession, dataProfession: WK_Profession): WK_TableDataCell
100 | ---@field toggleHidden boolean
101 |
102 | ---@class WK_TableData
103 | ---@field columns WK_TableDataColumn[]?
104 | ---@field rows WK_TableDataRow[]
105 |
106 | ---@class WK_TableDataColumn
107 | ---@field width number
108 | ---@field align string?
109 |
110 | ---@class WK_TableDataRow
111 | ---@field columns WK_TableDataCell[]
112 | ---@field backgroundColor {r: number, g: number, b: number, a: number}?
113 | ---@field onEnter function?
114 | ---@field onLeave function?
115 | ---@field onClick function?
116 |
117 | ---@class WK_TableDataCell
118 | ---@field text string?
119 | ---@field backgroundColor {r: number, g: number, b: number, a: number}?
120 | ---@field onEnter function?
121 | ---@field onLeave function?
122 | ---@field onClick function?
123 |
124 | ---@enum Enum.WK_Objectives
125 | Enum.WK_Objectives = {
126 | Unique = "Unique",
127 | Treatise = "Treatise",
128 | ArtisanQuest = "ArtisanQuest",
129 | Treasure = "Treasure",
130 | Gathering = "Gathering",
131 | TrainerQuest = "TrainerQuest",
132 | DarkmoonQuest = "DarkmoonQuest",
133 | CatchUp = "CatchUp",
134 | }
135 |
--------------------------------------------------------------------------------
/Utils.lua:
--------------------------------------------------------------------------------
1 | ---@type string
2 | local addonName = select(1, ...)
3 | ---@class WK_Addon
4 | local addon = select(2, ...)
5 |
6 | ---@class WK_Utils
7 | local Utils = {}
8 | addon.Utils = Utils
9 |
10 | ---Set the background color for a parent frame
11 | ---@param parent any
12 | ---@param r number?
13 | ---@param g number?
14 | ---@param b number?
15 | ---@param a number?
16 | function Utils:SetBackgroundColor(parent, r, g, b, a)
17 | if not parent.Background then
18 | parent.Background = parent:CreateTexture("Background", "BACKGROUND")
19 | parent.Background:SetTexture("Interface/BUTTONS/WHITE8X8")
20 | parent.Background:SetAllPoints()
21 | end
22 |
23 | if type(r) == "table" then
24 | r, g, b, a = r.a, r.g, r.b, r.a
25 | end
26 |
27 | if type(r) == nil then
28 | r, g, b, a = 0, 0, 0, 0.1
29 | end
30 |
31 | parent.Background:SetVertexColor(r, g, b, a)
32 | end
33 |
34 | ---Set the highlight color for a parent frame
35 | ---@param parent any
36 | ---@param r number?
37 | ---@param g number?
38 | ---@param b number?
39 | ---@param a number?
40 | function Utils:SetHighlightColor(parent, r, g, b, a)
41 | if not parent.Highlight then
42 | parent.Highlight = parent:CreateTexture("Highlight", "OVERLAY")
43 | parent.Highlight:SetTexture("Interface/BUTTONS/WHITE8X8")
44 | parent.Highlight:SetAllPoints()
45 | end
46 |
47 | if type(r) == "table" then
48 | r, g, b, a = r.a, r.g, r.b, r.a
49 | end
50 |
51 | if type(r) == nil then
52 | r, g, b, a = 1, 1, 1, 0.1
53 | end
54 |
55 | parent.Highlight:SetVertexColor(r, g, b, a)
56 | end
57 |
58 | ---Find a table item by callback
59 | ---@generic T
60 | ---@param tbl T[]
61 | ---@param callback fun(value: T, index: number): boolean
62 | ---@return T|nil, number|nil
63 | function Utils:TableFind(tbl, callback)
64 | for i, v in pairs(tbl) do
65 | if callback(v, i) then
66 | return v, i
67 | end
68 | end
69 | return nil, nil
70 | end
71 |
72 | ---Find a table item by key and value
73 | ---@generic T
74 | ---@param tbl T[]
75 | ---@param key string
76 | ---@param val any
77 | ---@return T|nil
78 | function Utils:TableGet(tbl, key, val)
79 | return self:TableFind(tbl, function(elm)
80 | return elm[key] and elm[key] == val
81 | end)
82 | end
83 |
84 | ---Create a new table containing all elements that pass truth test
85 | ---@generic T
86 | ---@param tbl T[]
87 | ---@param callback fun(value: T, index: number): boolean
88 | ---@return T[]
89 | function Utils:TableFilter(tbl, callback)
90 | local t = {}
91 | for i, v in pairs(tbl) do
92 | if callback(v, i) then
93 | table.insert(t, v)
94 | end
95 | end
96 | return t
97 | end
98 |
99 | ---Count table items
100 | ---@param tbl table
101 | ---@return number
102 | function Utils:TableCount(tbl)
103 | local n = 0
104 | for _ in pairs(tbl) do
105 | n = n + 1
106 | end
107 | return n
108 | end
109 |
110 | ---Deep copy a table
111 | ---@generic T
112 | ---@param tbl T[]
113 | ---@param cache table?
114 | ---@return T[]
115 | function Utils:TableCopy(tbl, cache)
116 | local t = {}
117 | cache = cache or {}
118 | cache[tbl] = t
119 | self:TableForEach(tbl, function(v, k)
120 | if type(v) == "table" then
121 | t[k] = cache[v] or self:TableCopy(v, cache)
122 | else
123 | t[k] = v
124 | end
125 | end)
126 | return t
127 | end
128 |
129 | ---Map each item in a table
130 | ---@generic T
131 | ---@param tbl T[]
132 | ---@param callback fun(value: T, index: number): any
133 | ---@return T[]
134 | function Utils:TableMap(tbl, callback)
135 | local t = {}
136 | self:TableForEach(tbl, function(v, k)
137 | local newv, newk = callback(v, k)
138 | t[newk and newk or k] = newv
139 | end)
140 | return t
141 | end
142 |
143 | ---Run a callback on each table item
144 | ---@generic T
145 | ---@param tbl T[]
146 | ---@param callback fun(value: T, index: number)
147 | ---@return T[]
148 | function Utils:TableForEach(tbl, callback)
149 | assert(tbl, "Must be a table!")
150 | for ik, iv in pairs(tbl) do
151 | callback(iv, ik)
152 | end
153 | return tbl
154 | end
155 |
--------------------------------------------------------------------------------
/WeeklyKnowledge.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 110100
2 | ## Title: WeeklyKnowledge
3 | ## Notes: Track your profession knowledge across your characters
4 | ## Version: @project-version@
5 | ## IconTexture: Interface\AddOns\WeeklyKnowledge\Media\Icon.blp
6 | ## SavedVariables: WeeklyKnowledgeDB
7 | ## X-Website: https://github.com/DennisRas/WeeklyKnowledge
8 | ## X-Curse-Project-ID: 1092009
9 | ## X-Wago-ID: qKQx0o6x
10 | ## X-WoWI-ID: 26821
11 | ## Category-enUS: Professions
12 | ## Category-deDE: Berufe
13 | ## Category-esES: Profesiones
14 | ## Category-esMX: Profesiones
15 | ## Category-frFR: Métiers
16 | ## Category-itIT: Professioni
17 | ## Category-koKR: 전문 기술
18 | ## Category-ptBR: Profissões
19 | ## Category-ruRU: Профессии
20 | ## Category-zhCN: 专业
21 | ## Category-zhTW: 專業技能
22 |
23 | Libs\LibStub\LibStub.lua
24 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
25 | Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
26 | Libs\LibDBIcon-1.0\lib.xml
27 |
28 | Libs\AceAddon-3.0\AceAddon-3.0.xml
29 | Libs\AceEvent-3.0\AceEvent-3.0.xml
30 | Libs\AceTimer-3.0\AceTimer-3.0.xml
31 | Libs\AceBucket-3.0\AceBucket-3.0.xml
32 | Libs\AceDB-3.0\AceDB-3.0.xml
33 | Libs\AceConsole-3.0\AceConsole-3.0.xml
34 | Libs\AceGUI-3.0\AceGUI-3.0.xml
35 | Libs\AceConfig-3.0\AceConfig-3.0.xml
36 |
37 | Types.lua
38 | Constants.lua
39 | Utils.lua
40 | Interface.lua
41 | Data.lua
42 |
43 | Checklist.lua
44 | Main.lua
45 | Core.lua
46 |
--------------------------------------------------------------------------------