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