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