Mercurial > wow > buffalo2
comparison ObjectiveWidgets.lua @ 13:9455693fc290
Init
- recall XML display state on reload
ObjectiveFrame
- quest coloring by relative level
- quest coloring by daily/weekly/complete status
- remember starting scroll value between reload
- limit anchor points to edges for regions affected by style attributes
ObjectiveInfo
- AutoQuest outline definitions
- Pull Quest title and tag data in addition to WatchInfo
ObjectiveStyle
- ensure consistent style table
- hardcode certain attributes for sanity
XML
- ensure consistent naming conventions for heading and content elements
- ensure hardcore anchors are based on edges
- expansion of file structure to deal with complexities of dynamic widgets and style caching
ObjectiveUI
- determine primary style by block handler when restoring original style
- moved framescript to 'ObjectiveWidgets' lua
author | Nenue |
---|---|
date | Sat, 02 Apr 2016 17:46:52 -0400 |
parents | |
children | ed642234f017 |
comparison
equal
deleted
inserted
replaced
12:8238cddaddb1 | 13:9455693fc290 |
---|---|
1 local B = select(2,...).frame | |
2 local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') | |
3 local print = B.print('WidgetFactory') | |
4 local UIParent = UIParent | |
5 local GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown | |
6 local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll | |
7 local tremove, tinsert, tContains, pairs, setmetatable = tremove, tinsert, tContains, pairs, setmetatable | |
8 ---------------------------------------------------------------------------------------- | |
9 --- XML and script code lifted from "QuestKing 2" by Barjack, | |
10 --- found at http://mods.curse.com/addons/wow/questking | |
11 ---------------------------------------------------------------------------------------- | |
12 local usedButtons = mod.Quest.itemButtons | |
13 local freeButtons = mod.Quest.freeButtons | |
14 mod.SetItemButton = function(block, info) | |
15 local itemInfo = info.specialItem | |
16 if not itemInfo then | |
17 return | |
18 end | |
19 | |
20 --- Quest.GetInfo().specialItem :: {link = link, charges = charges, icon = icon, start = start, duration = duration, enable = enable} | |
21 | |
22 | |
23 local itemButton | |
24 if not info.itemButton then | |
25 if #freeButtons >= 1 then | |
26 print(' |cFF00FFFFfound a free button') | |
27 itemButton = freeButtons[#freeButtons] | |
28 freeButtons[#freeButtons] = nil | |
29 if itemButton.block then | |
30 itemButton.block.itemButton = nil | |
31 itemButton.block = nil | |
32 end | |
33 else | |
34 local buttonIndex = mod.Quest.numButtons + #freeButtons + 1 | |
35 itemButton = CreateFrame('Button', 'VeneerQuestItemButton' .. buttonIndex, UIParent, 'VeneerItemButtonTemplate') | |
36 itemButton.buttonIndex = buttonIndex | |
37 itemButton:SetSize(36, 36) | |
38 itemButton:GetNormalTexture():SetSize(36 * (5/3), 36 * (5/3)) | |
39 print(' |cFFFF4400starting new button', itemButton:GetName()) | |
40 end | |
41 mod.Quest.numButtons = mod.Quest.numButtons + 1 | |
42 else | |
43 itemButton = info.itemButton | |
44 print(' |cFF00FF00found assigned button', itemButton:GetName()) | |
45 | |
46 end | |
47 -- set values | |
48 | |
49 info.itemButton = itemButton | |
50 usedButtons[info.questID] = itemButton | |
51 print(' |cFF8800FFassigning|r', itemButton:GetName(), 'to quest|cFF00FF00', info.questID, '|rat|cFFFFFF00', block:GetName(),'|r') | |
52 | |
53 for k,v in pairs(usedButtons) do | |
54 print('|cFFFF44DD'..k..'|r', v:GetName()) | |
55 end | |
56 | |
57 itemButton:SetAttribute("type", "item") | |
58 itemButton:SetAttribute("item", itemInfo.link) | |
59 | |
60 itemButton.questID = info.questID | |
61 itemButton.questLogIndex = info.questLogIndex | |
62 itemButton.charges = itemInfo.charges | |
63 itemButton.rangeTimer = -1 | |
64 itemButton.block = block | |
65 | |
66 SetItemButtonTexture(itemButton, itemInfo.icon) | |
67 SetItemButtonCount(itemButton, itemInfo.charges) | |
68 Veneer_QuestObjectiveItem_UpdateCooldown(itemButton); | |
69 | |
70 return itemButton | |
71 end | |
72 --- Clear an itemButton from the given block | |
73 mod.FreeItemButtons = function(block) | |
74 | |
75 if block.itemButton then | |
76 local itemButton = block.itemButton | |
77 if itemButton.questID ~= block.info.questID then | |
78 block.itemButton = nil | |
79 itemButton.block = mod.Quest.InfoBlock[itemButton.questID] | |
80 else | |
81 itemButton.block = nil | |
82 itemButton:Hide() | |
83 | |
84 usedButtons[itemButton.questID] = nil | |
85 freeButtons[#freeButtons + 1] = itemButton | |
86 mod.Quest.numButtons = mod.Quest.numButtons - 1 | |
87 print('|cFFFF0088released', itemButton:GetName(),'and', block:GetName()) | |
88 end | |
89 end | |
90 end | |
91 | |
92 function Veneer_QuestObjectiveItem_OnUpdate (self, elapsed) | |
93 -- Handle range indicator | |
94 local rangeTimer = self.rangeTimer | |
95 if (rangeTimer) then | |
96 rangeTimer = rangeTimer - elapsed | |
97 if (rangeTimer <= 0) then | |
98 local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.questLogIndex) | |
99 if ((not charges) or (charges ~= self.charges)) then | |
100 mod.UpdateWrapper() | |
101 return | |
102 end | |
103 | |
104 local count = self.HotKey | |
105 local valid = IsQuestLogSpecialItemInRange(self.questLogIndex) | |
106 if (valid == 0) then | |
107 count:Show() | |
108 count:SetVertexColor(1.0, 0.1, 0.1) | |
109 elseif (valid == 1) then | |
110 count:Show() | |
111 count:SetVertexColor(0.6, 0.6, 0.6) | |
112 else | |
113 count:Hide() | |
114 end | |
115 rangeTimer = TOOLTIP_UPDATE_TIME | |
116 end | |
117 | |
118 self.rangeTimer = rangeTimer | |
119 end | |
120 end | |
121 | |
122 function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton) | |
123 local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.questLogIndex) | |
124 if (start) then | |
125 CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable) | |
126 if (duration > 0 and enable == 0) then | |
127 SetItemButtonTextureVertexColor(itemButton, 0.4, 0.4, 0.4) | |
128 else | |
129 SetItemButtonTextureVertexColor(itemButton, 1, 1, 1) | |
130 end | |
131 end | |
132 end | |
133 | |
134 ----------------------------------------- | |
135 -- Criteria frames | |
136 | |
137 --[[ | |
138 text = description, | |
139 type = type, | |
140 finished = completed, | |
141 quantity = quantity, | |
142 requiredQuantity = requiredQuantity, | |
143 characterName = characterName, | |
144 flags = flags, | |
145 assetID = assetID, | |
146 quantityString = quantityString, | |
147 criteriaID = criteriaID, | |
148 ]] | |
149 local newWidgetID = 0 | |
150 mod.WidgetRegistry = {} | |
151 local wr = mod.WidgetRegistry | |
152 | |
153 --- Get a usable widget for the given achievement criteria set. | |
154 -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block | |
155 mod.SetWidget = function(obj, info) | |
156 local print = B.print('ObjectiveWidgets') | |
157 local widgetType = obj.type | |
158 local widget | |
159 if wr[widgetType] and wr[widgetType].used[obj.criteriaID] then | |
160 widget = wr[widgetType].used[obj.criteriaID] | |
161 print('|cFF00FF00Updating ('..obj.criteriaID..')', widget) | |
162 elseif not wr[widgetType] or #wr[widgetType].free == 0 then | |
163 widget = CreateFrame('Frame', 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) | |
164 | |
165 print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) | |
166 else | |
167 widget = tremove(wr[widgetType].free) | |
168 print('|cFFFFFF00Acquiring released widget', widget:GetName()) | |
169 end | |
170 | |
171 wr[widgetType].used[obj.criteriaID] = widget | |
172 widget.info = obj | |
173 widget.parentInfo = info | |
174 mod.InitializeWidget(widget) | |
175 return widget | |
176 end | |
177 | |
178 --- WidgetTemplate 'OnLoad' | |
179 mod.RegisterWidget = function(frame) | |
180 local print = B.print('ObjectiveWidgets') | |
181 local widgetType = frame.widgetType | |
182 if not wr[frame.widgetType] then | |
183 print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) | |
184 wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } | |
185 else | |
186 print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) | |
187 wr[widgetType].lastn = wr[widgetType].lastn + 1 | |
188 end | |
189 end | |
190 | |
191 --- WidgetTemplate 'OnShow' | |
192 mod.InitializeWidget = setmetatable({}, { | |
193 __call = function(t, frame) | |
194 -- todo: config pull | |
195 local maxWidth = 250 | |
196 | |
197 frame:SetWidth(maxWidth) | |
198 mod.UpdateWidget[frame.widgetType](frame) | |
199 frame:SetScript('OnEvent', mod.UpdateWidget[frame.widgetType]) | |
200 if frame.info.isCurrency then | |
201 frame:RegisterEvent('CHAT_MSG_CURRENCY') | |
202 frame:RegisterEvent('CURRENCY_LIST_UPDATE') | |
203 end | |
204 frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') | |
205 frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') | |
206 frame:RegisterEvent('CRITERIA_UPDATE') | |
207 frame:RegisterEvent('CRITERIA_COMPLETE') | |
208 frame:RegisterEvent('CRITERIA_EARNED') | |
209 | |
210 return t[frame.widgetType](frame) | |
211 end, | |
212 }) | |
213 | |
214 --- WidgetTemplate 'OnEvent' | |
215 mod.UpdateWidget = setmetatable({}, { | |
216 __call = function(t, frame) | |
217 if not frame.widgetType then | |
218 error('Invalid widget template, needs .widgetType') | |
219 return | |
220 end | |
221 | |
222 return t[frame.widgetType](frame) | |
223 end | |
224 }) | |
225 | |
226 --- WidgetTemplate 'OnHide' | |
227 mod.ReleaseWidget = function(frame) | |
228 local print = B.print('ObjectiveWidgets') | |
229 local reg = wr[frame.widgetType] | |
230 if reg and reg.used[frame.info.criteriaID] then | |
231 reg.used[frame.info.criteriaID] = nil | |
232 frame.info = nil | |
233 frame.parentInfo = nil | |
234 frame:UnregisterAllEvents() | |
235 tinsert(reg.free, frame) | |
236 print('|cFFBBBBBBreleased from service', frame:GetName()) | |
237 end | |
238 end | |
239 | |
240 --- RemoveTrackedAchievement post-hook | |
241 mod.CleanWidgets = function() | |
242 local print = B.print('ObjectiveWidgets') | |
243 local tracked = {GetTrackedAchievements() } | |
244 for type, reg in pairs(mod.WidgetRegistry) do | |
245 print('collecting', type) | |
246 for criteriaID, frame in pairs(reg.used) do | |
247 local id = frame.info.cheevID | |
248 | |
249 if id and not tContains(tracked, id) then | |
250 | |
251 print(' untracked achievement', id, 'associated with', criteriaID, frame:GetName()) | |
252 frame:Hide() | |
253 end | |
254 end | |
255 end | |
256 end | |
257 | |
258 | |
259 mod.defaults.WidgetVars = { | |
260 ProgressBar = { | |
261 bg = { | |
262 Height = 20, | |
263 }, | |
264 fg = { | |
265 Height = 16, | |
266 }, | |
267 status = { | |
268 FontObject = _G.VeneerFontNormal | |
269 } | |
270 } | |
271 } | |
272 mod.InitializeWidget.ProgressBar = function(self) | |
273 local c = mod.defaults.WidgetVars.ProgressBar | |
274 local params = mod.WidgetParams[self.widgetType] | |
275 self.height = params.height | |
276 self:SetHeight(c.bg.Height) | |
277 self.bg:SetHeight(c.bg.Height) | |
278 self.fg:ClearAllPoints() | |
279 self.fg:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 2, 2) | |
280 self.fg:SetHeight(c.fg.Height) | |
281 self.status:SetFontObject(c.status.FontObject) | |
282 self.status:SetText(self.info.quantityString) | |
283 end | |
284 | |
285 mod.UpdateWidget.ProgressBar = function (self) | |
286 local quantity, requiredQuantity = self.info.quantity, self.info.requiredQuantity | |
287 | |
288 if self.info.finished then | |
289 self.fg:SetWidth(self.bg:GetWidth() - 4) | |
290 elseif quantity == 0 then | |
291 self.fg:Hide() | |
292 else | |
293 self.fg:Show() | |
294 self.fg:SetWidth((self.bg:GetWidth()-4) * (quantity / requiredQuantity)) | |
295 end | |
296 end | |
297 | |
298 | |
299 mod.InitializeWidget.Hidden = function (self) | |
300 self.height = 0 | |
301 end | |
302 mod.UpdateWidget.Hidden = function (self) | |
303 self.height= 0 | |
304 end |