Mercurial > wow > buffalo2
comparison ObjectiveTracker/ObjectiveWidgets.lua @ 23:e837384ac363
Separating objective tracker module
author | Nenue |
---|---|
date | Sun, 10 Apr 2016 04:35:32 -0400 |
parents | ObjectiveWidgets.lua@9b3fa734abff |
children | 66b927b46776 |
comparison
equal
deleted
inserted
replaced
22:9b3fa734abff | 23:e837384ac363 |
---|---|
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 --- frame refs | |
10 local Wrapper = _G.VeneerObjectiveWrapper | |
11 local Scroller = Wrapper.scrollArea | |
12 local CloseButton = Wrapper.CloseButton | |
13 local QuestMapButton = Wrapper.QuestMapButton | |
14 local Scroll = _G.VeneerObjectiveScroll | |
15 | |
16 local panelButtons = { | |
17 CloseButton = { | |
18 closedSwatch = { | |
19 [[Interface\Buttons\UI-Panel-QuestHideButton]], | |
20 [[Interface\Buttons\UI-Panel-QuestHideButton]], | |
21 0, 0.5, 0.5, 1, | |
22 0.5, 1, 0.5, 1, | |
23 }, | |
24 openSwatch = { | |
25 [[Interface\Buttons\UI-Panel-QuestHideButton]], | |
26 [[Interface\Buttons\UI-Panel-QuestHideButton]], | |
27 0.5, 1, 0.5, 1, | |
28 0, 0.5, 0.5, 1, | |
29 }, | |
30 parent = 'VeneerObjectiveWrapper' | |
31 }, | |
32 QuestMapButton = { | |
33 closedSwatch = { | |
34 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], | |
35 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], | |
36 0, 1, 0.5, 1, | |
37 0, 1, 0, 0.5, | |
38 }, | |
39 openSwatch = { | |
40 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], | |
41 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], | |
42 0, 1, 0, 0.5, | |
43 0, 1, 0.5, 1, | |
44 } | |
45 } | |
46 } | |
47 | |
48 local Scroller_OnShow = function() | |
49 Wrapper.watchMoneyReasons = 0; | |
50 --mod:Update() | |
51 --mod:OnInitialize() | |
52 for i, region in ipairs(Wrapper.headerComplex) do | |
53 region:Show() | |
54 end | |
55 end | |
56 | |
57 local Scroller_OnHide = function() | |
58 local self = Wrapper | |
59 Wrapper:UnregisterAllEvents() | |
60 Wrapper:SetScript('OnEvent', nil) | |
61 for i, region in ipairs(Wrapper.headerComplex) do | |
62 region:Hide() | |
63 end | |
64 end | |
65 | |
66 local Scroller_OnMouseWheel = function(self, delta) | |
67 local r = Scroll:GetHeight() - Scroller:GetHeight() | |
68 local s = B.Conf.ObjectiveScroll - delta * floor(r/5+.5) | |
69 local from = self:GetVerticalScroll() | |
70 print('|cFF00FF00OnMouseWheel', 'scroll =', s) | |
71 if s >= r then | |
72 s = r | |
73 elseif s < 1 then | |
74 s = 0 | |
75 end | |
76 self:SetVerticalScroll(s) | |
77 B.Conf.ObjectiveScroll = s | |
78 print('|cFF00FF00OnMouseWheel', 'from = ', from, 'scroll =', s, ' range =', r, 'current =', self:GetVerticalScroll()) | |
79 | |
80 mod.UpdateActionButtons('SCROLLING') | |
81 end | |
82 | |
83 local UpdatePanelButton = function (self, state) | |
84 state = state and B.Conf.FrameState[state] or 1 | |
85 local swatch = (state == 1) and self.openSwatch or self.closedSwatch | |
86 self:SetNormalTexture(swatch[1]) | |
87 self:SetPushedTexture(swatch[2]) | |
88 if #swatch >= 6 then | |
89 self:GetNormalTexture():SetTexCoord(swatch[3], swatch[4], swatch[5], swatch[6]) | |
90 end | |
91 if #swatch == 10 then | |
92 self:GetPushedTexture():SetTexCoord(swatch[7], swatch[8], swatch[9], swatch[10]) | |
93 end | |
94 | |
95 end | |
96 | |
97 local OnClick = {} | |
98 OnClick.CloseButton = function(self) | |
99 Wrapper:Minimize() | |
100 UpdatePanelButton(self, self.parent) | |
101 end | |
102 | |
103 OnClick.QuestMapButton = function() | |
104 ToggleWorldMap() | |
105 end | |
106 | |
107 | |
108 mod.InitializeWidgets = function() | |
109 --- tracker scroll | |
110 Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel) | |
111 Scroller:SetScript('OnShow', Scroller_OnShow) | |
112 Scroller:SetScript('OnHide', Scroller_OnHide) | |
113 for name, swatch in pairs(panelButtons) do | |
114 local source = swatch and swatch or panelButtons.CloseButton | |
115 local button = Wrapper[name] | |
116 button.parent = swatch.parent | |
117 button.openSwatch = source.openSwatch | |
118 button.closedSwatch = source.closedSwatch | |
119 if OnClick[name] then | |
120 button:SetScript('OnClick', OnClick[name]) | |
121 end | |
122 UpdatePanelButton(button, button.parent) | |
123 end | |
124 end | |
125 | |
126 ---------------------------------------------------------------------------------------- | |
127 --- XML and script code lifted from "QuestKing 2" by Barjack, | |
128 --- found at http://mods.curse.com/addons/wow/questking | |
129 ---------------------------------------------------------------------------------------- | |
130 local usedButtons = mod.Quest.itemButtons | |
131 local freeButtons = mod.Quest.freeButtons | |
132 mod.SetItemButton = function(block, info) | |
133 local itemInfo = info.specialItem | |
134 if not itemInfo then | |
135 return | |
136 end | |
137 | |
138 --- Quest.GetInfo().specialItem :: {link = link, charges = charges, icon = icon, start = start, duration = duration, enable = enable} | |
139 | |
140 | |
141 local itemButton | |
142 if not info.itemButton then | |
143 if #freeButtons >= 1 then | |
144 print(' |cFF00FFFFfound a free button') | |
145 itemButton = freeButtons[#freeButtons] | |
146 freeButtons[#freeButtons] = nil | |
147 if itemButton.block then | |
148 itemButton.block.itemButton = nil | |
149 itemButton.block = nil | |
150 end | |
151 else | |
152 local buttonIndex = mod.Quest.numButtons + #freeButtons + 1 | |
153 itemButton = CreateFrame('Button', 'VeneerQuestItemButton' .. buttonIndex, UIParent, 'VeneerItemButtonTemplate') | |
154 itemButton.buttonIndex = buttonIndex | |
155 itemButton:SetSize(36, 36) | |
156 itemButton:GetNormalTexture():SetSize(36 * (5/3), 36 * (5/3)) | |
157 print(' |cFFFF4400starting new button', itemButton:GetName()) | |
158 end | |
159 mod.Quest.numButtons = mod.Quest.numButtons + 1 | |
160 else | |
161 itemButton = info.itemButton | |
162 print(' |cFF00FF00found assigned button', itemButton:GetName()) | |
163 | |
164 end | |
165 -- set values | |
166 | |
167 info.itemButton = itemButton | |
168 usedButtons[info.questID] = itemButton | |
169 print(' |cFF8800FFassigning|r', itemButton:GetName(), 'to quest|cFF00FF00', info.questID, '|rat|cFFFFFF00', block:GetName(),'|r') | |
170 | |
171 for k,v in pairs(usedButtons) do | |
172 print('|cFFFF44DD'..k..'|r', v:GetName()) | |
173 end | |
174 | |
175 itemButton:SetAttribute("type", "item") | |
176 itemButton:SetAttribute("item", itemInfo.link) | |
177 | |
178 itemButton.questID = info.questID | |
179 itemButton.questLogIndex = info.questLogIndex | |
180 itemButton.charges = itemInfo.charges | |
181 itemButton.rangeTimer = -1 | |
182 itemButton.block = block | |
183 | |
184 SetItemButtonTexture(itemButton, itemInfo.icon) | |
185 SetItemButtonCount(itemButton, itemInfo.charges) | |
186 Veneer_QuestObjectiveItem_UpdateCooldown(itemButton); | |
187 | |
188 return itemButton | |
189 end | |
190 --- Clear an itemButton from the given block | |
191 mod.FreeItemButtons = function(block) | |
192 | |
193 if block.itemButton then | |
194 local itemButton = block.itemButton | |
195 if itemButton.questID ~= block.info.questID then | |
196 block.itemButton = nil | |
197 itemButton.block = mod.Quest.InfoBlock[itemButton.questID] | |
198 else | |
199 itemButton.block = nil | |
200 itemButton:Hide() | |
201 | |
202 usedButtons[itemButton.questID] = nil | |
203 freeButtons[#freeButtons + 1] = itemButton | |
204 mod.Quest.numButtons = mod.Quest.numButtons - 1 | |
205 print('|cFFFF0088released', itemButton:GetName(),'and', block:GetName()) | |
206 end | |
207 end | |
208 end | |
209 | |
210 function Veneer_QuestObjectiveItem_OnUpdate (self, elapsed) | |
211 -- Handle range indicator | |
212 local rangeTimer = self.rangeTimer | |
213 if (rangeTimer) then | |
214 rangeTimer = rangeTimer - elapsed | |
215 if (rangeTimer <= 0) then | |
216 local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.questLogIndex) | |
217 if ((not charges) or (charges ~= self.charges)) then | |
218 mod:Update() | |
219 return | |
220 end | |
221 | |
222 local count = self.HotKey | |
223 local valid = IsQuestLogSpecialItemInRange(self.questLogIndex) | |
224 if (valid == 0) then | |
225 count:Show() | |
226 count:SetVertexColor(1.0, 0.1, 0.1) | |
227 elseif (valid == 1) then | |
228 count:Show() | |
229 count:SetVertexColor(0.6, 0.6, 0.6) | |
230 else | |
231 count:Hide() | |
232 end | |
233 rangeTimer = TOOLTIP_UPDATE_TIME | |
234 end | |
235 | |
236 self.rangeTimer = rangeTimer | |
237 end | |
238 end | |
239 | |
240 function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton) | |
241 local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.questLogIndex) | |
242 if (start) then | |
243 CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable) | |
244 if (duration > 0 and enable == 0) then | |
245 SetItemButtonTextureVertexColor(itemButton, 0.4, 0.4, 0.4) | |
246 else | |
247 SetItemButtonTextureVertexColor(itemButton, 1, 1, 1) | |
248 end | |
249 end | |
250 end | |
251 | |
252 ----------------------------------------- | |
253 -- Criteria frames | |
254 | |
255 --[[ | |
256 text = description, | |
257 type = type, | |
258 finished = completed, | |
259 quantity = quantity, | |
260 requiredQuantity = requiredQuantity, | |
261 characterName = characterName, | |
262 flags = flags, | |
263 assetID = assetID, | |
264 quantityString = quantityString, | |
265 criteriaID = criteriaID, | |
266 ]] | |
267 local newWidgetID = 0 | |
268 mod.WidgetRegistry = {} | |
269 local wr = mod.WidgetRegistry | |
270 | |
271 --- Get a usable widget for the given achievement criteria set. | |
272 -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block | |
273 mod.SetWidget = function(line, data, objectiveType, objectiveKey) | |
274 local print = B.print('ObjectiveWidgets') | |
275 local widgetType = objectiveType | |
276 local widget | |
277 if wr[widgetType] and wr[widgetType].used[objectiveKey] then | |
278 widget = wr[widgetType].used[objectiveKey] | |
279 print('|cFF00FF00Updating ('..objectiveKey..')', widget) | |
280 elseif not wr[widgetType] or #wr[widgetType].free == 0 then | |
281 widget = CreateFrame('Frame', 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) | |
282 | |
283 print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) | |
284 else | |
285 widget = tremove(wr[widgetType].free) | |
286 print('|cFFFFFF00Acquiring released widget', widget:GetName()) | |
287 end | |
288 | |
289 | |
290 wr[widgetType].used[objectiveKey] = widget | |
291 widget.line = line | |
292 widget.objective = data | |
293 widget.key = objectiveKey | |
294 mod.InitializeWidget(widget) | |
295 return widget | |
296 end | |
297 | |
298 --- WidgetTemplate 'OnLoad' | |
299 mod.RegisterWidget = function(frame) | |
300 local print = B.print('ObjectiveWidgets') | |
301 local widgetType = frame.widgetType | |
302 if not wr[frame.widgetType] then | |
303 print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) | |
304 wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } | |
305 else | |
306 print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) | |
307 wr[widgetType].lastn = wr[widgetType].lastn + 1 | |
308 end | |
309 end | |
310 | |
311 --- WidgetTemplate 'OnShow' | |
312 mod.InitializeWidget = setmetatable({}, { | |
313 __call = function(t, frame) | |
314 -- todo: config pull | |
315 | |
316 frame:SetWidth(mod.Conf.Wrapper.Width - mod.Conf.Style.Format.status.Indent * 2) | |
317 frame:SetScript('OnEvent', mod.UpdateWidget[frame.widgetType]) | |
318 frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') | |
319 frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') | |
320 frame:RegisterEvent('CRITERIA_UPDATE') | |
321 frame:RegisterEvent('CRITERIA_COMPLETE') | |
322 frame:RegisterEvent('CRITERIA_EARNED') | |
323 t[frame.widgetType](frame) | |
324 mod.UpdateWidget[frame.widgetType](frame) | |
325 end, | |
326 }) | |
327 | |
328 --- WidgetTemplate 'OnEvent' | |
329 mod.UpdateWidget = setmetatable({}, { | |
330 __call = function(t, frame) | |
331 if not frame.widgetType then | |
332 error('Invalid widget template, needs .widgetType') | |
333 return | |
334 end | |
335 | |
336 return t[frame.widgetType](frame) | |
337 end | |
338 }) | |
339 | |
340 --- WidgetTemplate 'OnHide' | |
341 mod.ReleaseWidget = function(frame) | |
342 --[[ | |
343 local print = B.print('ObjectiveWidgets') | |
344 local reg = wr[frame.widgetType] | |
345 if reg and reg.used[frame.key] then | |
346 reg.used[frame.key] = nil | |
347 frame.line = nil | |
348 frame.info = nil | |
349 frame:UnregisterAllEvents() | |
350 tinsert(reg.free, frame) | |
351 print('|cFFBBBBBBreleased from service', frame:GetName()) | |
352 end | |
353 ]] | |
354 end | |
355 | |
356 --- RemoveTrackedAchievement post-hook | |
357 mod.CleanWidgets = function() | |
358 local print = B.print('ObjectiveWidgets') | |
359 local tracked = {GetTrackedAchievements() } | |
360 local tasks = GetTasksTable() | |
361 for type, reg in pairs(mod.WidgetRegistry) do | |
362 print('collecting', type) | |
363 for key, frame in pairs(reg.used) do | |
364 if frame.objective.cheevID then | |
365 local id = frame.objective.cheevID | |
366 | |
367 if id and not tContains(tracked, id) then | |
368 | |
369 print(' untracked achievement', id, 'associated with', key, frame:GetName()) | |
370 frame:Hide() | |
371 end | |
372 elseif frame.objective.questID then | |
373 -- do something for quest task | |
374 end | |
375 end | |
376 end | |
377 end | |
378 | |
379 | |
380 | |
381 mod.defaults.WidgetStyle = { | |
382 | |
383 } | |
384 | |
385 local progressHeight = 16 | |
386 local progressBorder = 1 | |
387 local progressIndent = 3 | |
388 local progressFont = _G.VeneerCriteriaFontNormal | |
389 | |
390 | |
391 mod.InitializeWidget.ProgressBar = function(self) | |
392 local c = mod.Conf.Wrapper | |
393 self.height = progressHeight + c.TextSpacing | |
394 self.width = c.Width - c.TextSpacing | |
395 self.indent = progressIndent | |
396 | |
397 self:SetHeight(progressHeight) | |
398 self.bg:SetHeight(progressHeight) | |
399 self.bg:SetWidth(self.width) | |
400 self.fg:ClearAllPoints() | |
401 self.fg:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', progressBorder, progressBorder) | |
402 self.fg:SetHeight(progressHeight - progressBorder * 2) | |
403 self.status:SetFontObject(progressFont) | |
404 self.status:SetText(self.objective.quantityString) | |
405 end | |
406 | |
407 mod.UpdateWidget.ProgressBar = function (self) | |
408 local quantity, requiredQuantity = self.objective.value, self.objective.maxValue | |
409 print('update vals:') | |
410 for k,v in pairs(self.line) do | |
411 print(k, v) | |
412 end | |
413 | |
414 if self.line.format then | |
415 self.status:SetFormattedText(self.line.format, quantity, requiredQuantity) | |
416 end | |
417 | |
418 local progress = (quantity / requiredQuantity) | |
419 if progress >= 1 then | |
420 self.fg:Show() | |
421 self.fg:SetWidth(self.width - progressBorder * 2) | |
422 elseif progress > 0 then | |
423 self.fg:Show() | |
424 print('color:', 1-progress*2 , progress*2 - 1,0,1) | |
425 print('width:', (self.width -progressBorder * 2) * progress) | |
426 self.fg:SetTexture(1-progress*2 , progress*2,0,1) | |
427 self.fg:SetWidth((self.width -progressBorder * 2) * progress) | |
428 else | |
429 self.fg:Hide() | |
430 end | |
431 end | |
432 | |
433 | |
434 mod.InitializeWidget.Hidden = function (self) | |
435 self.height = 0 | |
436 end | |
437 mod.UpdateWidget.Hidden = function (self) | |
438 self.height= 0 | |
439 end |