Mercurial > wow > buffalo2
comparison ObjectiveTracker/ObjectiveFrame.lua @ 23:e837384ac363
Separating objective tracker module
author | Nenue |
---|---|
date | Sun, 10 Apr 2016 04:35:32 -0400 |
parents | ObjectiveFrame.lua@9b3fa734abff |
children | 66b927b46776 |
comparison
equal
deleted
inserted
replaced
22:9b3fa734abff | 23:e837384ac363 |
---|---|
1 --- ${PACKAGE_NAME} | |
2 -- @file-author@ | |
3 -- @project-revision@ @project-hash@ | |
4 -- @file-revision@ @file-hash@ | |
5 -- Created: 3/30/2016 12:49 AM | |
6 local B = select(2,...).frame | |
7 local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') | |
8 local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band | |
9 local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion | |
10 local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent | |
11 local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText | |
12 local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent | |
13 local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs | |
14 local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame | |
15 local print = B.print('Tracker') | |
16 local unitLevel = 1 | |
17 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON | |
18 local debug = false | |
19 -------------------------------------------------------------------- | |
20 --- Global frame layout | |
21 -------------------------------------------------------------------- | |
22 | |
23 --- Upvalues | |
24 local Wrapper = _G.VeneerObjectiveWrapper | |
25 local Scroller = Wrapper.scrollArea | |
26 local Scroll = _G.VeneerObjectiveScroll | |
27 local orderedHandlers = T.orderedHandlers | |
28 local orderedNames = T.orderedNames | |
29 | |
30 --- Temp values set during updates | |
31 local wrapperWidth, wrapperHeight | |
32 local scrollWidth, scrollHeight | |
33 local previousBlock | |
34 local currentBlock | |
35 --- todo: source these from config | |
36 local itemButtonSize, itemButtonSpacing = 36, 1 | |
37 local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]] | |
38 local titleSize, textSize = 16, 16 | |
39 local titlebg, textbg = {'HORIZONTAL', 1, 0, .7, .25, 1, 0, .7, .125}, {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 } | |
40 local titlebg_daily, textbg_daily = {'HORIZONTAL', 0, .7, 1, .25, 0, 1, .7, .125}, {'HORIZONTAL', 0, .7, 1, .1, 0, 1, .7, .075 } | |
41 local textbg_account,titlebg_account = {'HORIZONTAL', 0, .45, 1, .25, 0, .45, 1, .125}, {'HORIZONTAL', 0, .45, 1, 0.4, 0, .41, 1, .085 } | |
42 local selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225} | |
43 local titleOutline, textOutline = "OUTLINE", "OUTLINE" | |
44 local titleSpacing, textSpacing, blockSpacing = 3, 3, 1 | |
45 local titleIndent, textIndent,selectionIndent = 2, 5, 50 | |
46 local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed | |
47 local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE' | |
48 local headerFont, headerSize, headerHeight = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 18, 24 | |
49 local headerOutline, headerColor, headerSpacing = 'OUTLINE', {1,1,1,1}, 2 | |
50 local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 } | |
51 local rewardSize = 32 | |
52 local oprint = B.print('Objectives') | |
53 local bprint = B.print('Block') | |
54 local tprint = B.print('Tracker') | |
55 local lprint = B.print('Line') | |
56 | |
57 local currentPosition, anchorFrame, anchorPoint | |
58 | |
59 T.colors ={ | |
60 default = { | |
61 titlebg = {'HORIZONTAL', 1, 0, .7, .25, 1, 0, .7, .125}, | |
62 textbg = {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 }, | |
63 selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225}, | |
64 }, | |
65 daily = { | |
66 titlebg = {'HORIZONTAL', 0, .7, 1, .25, 0, 1, .7, .125}, | |
67 textbg = {'HORIZONTAL', 0, .7, 1, .1, 0, 1, .7, .075 }, | |
68 }, | |
69 weekly = { | |
70 titlebg = {'HORIZONTAL', 0, .35, .7, .25, 0, .35, .7, .125}, | |
71 textbg = {'HORIZONTAL', 0, .35, .7, .1, 0, .35, .7, .075 }, | |
72 }, | |
73 account = { | |
74 titlebg = {'HORIZONTAL', .1, .1, .1, .25, .1, .1, .1, .125}, | |
75 textbg = {'HORIZONTAL', .1, .1, .1, 0.4, .1, .1, .1, .085 }, | |
76 }, | |
77 -- alliance | |
78 faction_1 = { | |
79 titlebg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 }, | |
80 textbg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 }, | |
81 }, | |
82 -- horde | |
83 faction_2 = { | |
84 titlebg = {'HORIZONTAL', .6, 0, 0.4, 0.4, .6, 0, 0.4, .085 }, | |
85 textbg = {'HORIZONTAL', .6, 0, 0.4, 0.4, .6, 0, 0.4, .085 }, | |
86 } | |
87 } | |
88 | |
89 T.AddBlock = function(handler, block) | |
90 local print = bprint | |
91 end | |
92 | |
93 --- Used as an iterator of sorts for cascaded tag icon placements (the daily/faction/account icons) | |
94 T.AddTag = function (block, tagName, tagPoint, tagAnchor, tagRelative) | |
95 local print = bprint | |
96 local tag = block[tagName] | |
97 if block.info[tagName] and tag then | |
98 tag:SetTexCoord(unpack(block.info[tagName])) | |
99 tag:Show() | |
100 tag:SetPoint(tagPoint, tagAnchor, tagRelative, 0, 0) | |
101 tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', tag, 'TOPLEFT' | |
102 else | |
103 block[tagName]:Hide() | |
104 end | |
105 return tagPoint, tagAnchor, tagRelative | |
106 end | |
107 | |
108 --- Adds the given line to the current content and advances the anchor pointer to that new line for the following call. | |
109 T.AddLine = function(block, line) | |
110 local print = lprint | |
111 line:ClearAllPoints() | |
112 line:SetPoint('LEFT', block, 'LEFT', 0, 0) | |
113 line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) | |
114 line:SetPoint('RIGHT', block, 'RIGHT', 0, 0) | |
115 line:SetHeight(line.height) | |
116 line:Show() | |
117 | |
118 block.endIndex = line.index | |
119 block.numLines = block.numLines + 1 | |
120 block.attachmentHeight = block.attachmentHeight + (line.height + textSpacing) | |
121 print(' |cFF0088FFsetting line #'..block.numLines..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, | |
122 "|cFF0088FFpoint:|r", line:GetPoint(1), "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) | |
123 block.endPoint = line | |
124 end | |
125 | |
126 --- Creates or retrieves a complete line data object | |
127 T.GetLine = function(handler, block, lineIndex) | |
128 local print = lprint | |
129 local blockIndex = block.index | |
130 if not block.lines then | |
131 block.lines = {} | |
132 end | |
133 local lines = block.lines | |
134 if not lines[lineIndex] then | |
135 print(' |cFF00FF88created line #'..lineIndex..' from for '..handler.name..' block #'..blockIndex) | |
136 lines[lineIndex] = CreateFrame('Frame', 'Vn'..handler.name .. blockIndex..'ObjectiveLine'..lineIndex, block, 'VeneerTrackerObjective') | |
137 local line = lines[lineIndex] | |
138 line.index = lineIndex | |
139 line.height = 0 | |
140 line.status:SetSpacing(textSpacing) | |
141 line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) | |
142 B.SetConfigLayers(line) | |
143 | |
144 if lines[lineIndex+1] then | |
145 lines[lineIndex+1]:ClearAllPoints() | |
146 end | |
147 | |
148 if debug then | |
149 for _, region in ipairs(lines[lineIndex].debug) do | |
150 region:Show() | |
151 end | |
152 end | |
153 | |
154 end | |
155 return lines[lineIndex] | |
156 end | |
157 | |
158 --- Creates or retrieves a complete block frame object | |
159 T.GetBlock = function(handler, blockIndex) | |
160 local print = bprint | |
161 local block = handler.usedBlocks[blockIndex] | |
162 | |
163 if not handler.usedBlocks[blockIndex] then | |
164 if #handler.freeBlocks >= 1 then | |
165 block = handler.freeBlocks[#handler.freeBlocks] | |
166 handler.freeBlocks[#handler.freeBlocks] = nil | |
167 else | |
168 block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock') | |
169 | |
170 | |
171 | |
172 local c = T.Conf.Wrapper | |
173 block.index = blockIndex | |
174 block.SetStyle = T.SetBlockStyle | |
175 block:SetWidth(c.Width) | |
176 | |
177 block.title:SetSpacing(c.TitleSpacing) | |
178 block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing) | |
179 | |
180 block.titlebg:SetTexture(1,1,1,1) | |
181 block.titlebg:SetGradientAlpha(unpack(colors.default.titlebg)) | |
182 block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0) | |
183 block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing) | |
184 | |
185 block.status:SetSpacing(c.TextSpacing) | |
186 block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing) | |
187 block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0) | |
188 | |
189 block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0) | |
190 block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0) | |
191 block.statusbg:SetTexture(1,1,1,1) | |
192 block.statusbg:SetGradientAlpha(unpack(colors.default.textbg)) | |
193 | |
194 block.SelectionOverlay:SetGradientAlpha(unpack(colors.default.selectionbg)) | |
195 block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0) | |
196 block.SelectionOverlay:SetPoint('BOTTOMRIGHT') | |
197 | |
198 block.icon:SetSize(rewardSize, rewardSize) | |
199 block.icon:SetPoint('TOPRIGHT', block, 'TOPRIGHT', -2, -2) | |
200 | |
201 | |
202 --- methods for event handlers | |
203 | |
204 block.Select = handler.Select | |
205 block.Open = handler.Open | |
206 block.Remove = handler.Remove | |
207 block.Link = handler.Link | |
208 block:SetScript('OnMouseUp', handler.OnMouseUp) | |
209 block:SetScript('OnMouseDown', handler.OnMouseDown) | |
210 block.attachmentHeight = 0 | |
211 block:ClearAllPoints() | |
212 | |
213 B.SetConfigLayers(block) | |
214 | |
215 if debug then | |
216 for _, region in ipairs(block.debug) do | |
217 region:Show() | |
218 end | |
219 end | |
220 end | |
221 handler.usedBlocks[blockIndex] = block | |
222 end | |
223 return handler.usedBlocks[blockIndex] | |
224 end | |
225 | |
226 --- Module-specific data wrangling that has to happen during UpdateBlock() | |
227 -- Most of this is sculpting objectives data into a parsible list. | |
228 -- Some of it is additional block manipulation that doesn't quite fit with the other modules.. | |
229 Bonus.UpdateObjectives = function(handler, block) | |
230 Default.UpdateObjectives(handler, block) | |
231 end | |
232 | |
233 | |
234 --- They are not exactly quests, but the aliases used to signal that a quest was pushed into your log by the environment. | |
235 -- Once accepted they never appear again unless the quest is dropped (daily reset/abandon quest) | |
236 local CLICK_TO_COMPLETE = 'Click to Complete' | |
237 local CLICK_TO_ACCEPT = 'Click to Accept' | |
238 AutoQuest.UpdateObjectives = function(handler, block) | |
239 local print = lprint | |
240 if block.info.type == 'OFFER' then | |
241 block.status:SetText(CLICK_TO_ACCEPT) | |
242 end | |
243 end | |
244 | |
245 | |
246 | |
247 | |
248 --- Does the main iterations for populating block content. | |
249 -- Hooked by corresponding handler functions where additional details need to be sorted. | |
250 Default.UpdateObjectives = function(handler, block) | |
251 local print = lprint | |
252 local info = block.info | |
253 print(' |cFF00FF00default objectives routine', block:GetName()) | |
254 | |
255 -- reset the starting positions | |
256 block.attachmentHeight = 0 | |
257 block.endPoint = block.titlebg | |
258 local completionScore, completionMax = 0, 0 | |
259 local displayObjectiveHeader = false | |
260 | |
261 if info.description and #info.description >= 1 then | |
262 print(' |cFF00FFFF header line:|r', info.description) | |
263 block.status:SetText(info.description) | |
264 displayObjectiveHeader = true | |
265 end | |
266 | |
267 --- The first line is going to be used no matter what, so it is hard-pulled. | |
268 -- It also ensures that we're in the right position for cleaning up the leftover lines. | |
269 local lineIndex = 1 | |
270 local line = T.GetLine(handler, block, lineIndex) | |
271 | |
272 block.numLines = 0 | |
273 block.attachmentHeight = 0 | |
274 if info.isComplete then | |
275 print(' overriding line #1 for a completed block') | |
276 if line.widget then | |
277 line.widget:Hide() | |
278 end | |
279 line.status:SetText(info.completionText) | |
280 line.height = floor(line.status:GetHeight()+.5) + textSpacing | |
281 T.AddLine(block, line) | |
282 else | |
283 if info.objectives then | |
284 for i, data in ipairs(info.objectives) do | |
285 print(' |cFF88FF00#', i, data.type, data.text) | |
286 displayObjectiveHeader = true | |
287 line.height = 0 | |
288 handler:UpdateLine(block, line, data) | |
289 | |
290 -- For progressbar and timer lines, status text may be used as the title heading | |
291 if line.widget then | |
292 local widgetPosition = 0 | |
293 --- WIDGET POSITION ------------------------------------------------- | |
294 line.widget:SetPoint('TOP', line, 'TOP', 0, -widgetPosition) | |
295 line.widget:Show() | |
296 line.height = line.widget:GetHeight() + textSpacing | |
297 --------------------------------------------------------------------- | |
298 if line.displayText and #line.displayText >= 1 then | |
299 widgetPosition = line.status:GetHeight() + textSpacing | |
300 line.status:SetText(line.displayText) | |
301 line.height = floor(line.status:GetStringHeight()+.5) + textSpacing + line.widget.height | |
302 print(' - progressbar has text, adjust') | |
303 end | |
304 elseif line.displayText then | |
305 line.status:SetText(line.displayText) | |
306 line.height = floor(line.status:GetStringHeight()+.5) | |
307 end | |
308 | |
309 T.AddLine(block, line) | |
310 | |
311 --print(' sz', line:GetWidth(), line:GetHeight(), 'pt', line:GetPoint(1)) | |
312 --print(' |cFF44BBFF#', i, 'anchoring line, size:', line.height, 'current endpoint:', line.statusbg) | |
313 | |
314 lineIndex = lineIndex + 1 | |
315 line = T.GetLine(handler, block, lineIndex) | |
316 end | |
317 end | |
318 end | |
319 | |
320 while (block.lines[lineIndex+1]) do | |
321 print(' - hide |cFFFF0088'..lineIndex..'|r') | |
322 block.lines[lineIndex]:Hide() | |
323 lineIndex = lineIndex +1 | |
324 end | |
325 | |
326 | |
327 | |
328 if lineIndex > 0 then | |
329 block.attachmentHeight = block.attachmentHeight + textSpacing * 2 | |
330 print(' |cFF00FF00attachment:', block.attachmentHeight) | |
331 end | |
332 | |
333 | |
334 --[[ | |
335 local lines = handler.lines[block.index] | |
336 if lines and #lines > block.numLines then | |
337 print(' |cFFFF008' .. (#lines - block.numLines) .. ' extra lines to hide.') | |
338 for i = block.numLines + 1, #lines do | |
339 print(' hide', i, lines[i]:GetName()) | |
340 lines[i]:Hide() | |
341 end | |
342 end | |
343 ]] | |
344 | |
345 | |
346 if debug then | |
347 for i, region in ipairs(block.debug) do | |
348 for j = 1, region:GetNumPoints() do | |
349 local _, target = region:GetPoint(j) | |
350 if target:IsVisible() then | |
351 region:Hide() | |
352 else | |
353 region:Show() | |
354 end | |
355 end | |
356 end | |
357 end | |
358 | |
359 block.completionScore = completionScore / completionMax | |
360 end | |
361 | |
362 | |
363 --- Module-specific display variables | |
364 -- * height - height of whatever display widget is involved in conveying the task | |
365 -- * money - boolean that determines listening for money events or not | |
366 -- * progress - number ranging 0 to 2 indicating none/partial/full completion respectively | |
367 | |
368 | |
369 | |
370 Bonus.UpdateLine = function(handler, block, line, data) | |
371 local info = block.info | |
372 local print = lprint | |
373 | |
374 | |
375 line.displayColor = 'FFFFFF' | |
376 line.displayText = data.text | |
377 line.progress = 0 | |
378 print(' ', data.objectiveIndex,'|cFFFF0088-|r', data.objectiveType, data.text) | |
379 if data.objectiveType == 'progressbar' then | |
380 line.widgetType = 'ProgressBar' | |
381 print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) | |
382 data.value = GetQuestProgressBarPercent(info.questID) or 0 | |
383 data.maxValue = 100 | |
384 if data.value >= data.maxValue then | |
385 line.progress = 1 | |
386 elseif data.value > 0 then | |
387 line.progress = 2 | |
388 end | |
389 line.format = PERCENTAGE_STRING | |
390 local widget = T.SetWidget(line, data, 'ProgressBar', info.questID..'-'..data.objectiveIndex) | |
391 print(' |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue) | |
392 widget:SetPoint('TOP', line, 'TOP', 0, 0) | |
393 | |
394 line.widget = widget | |
395 line.height = widget.height | |
396 else | |
397 line.displayText = data.text | |
398 line.widget = nil | |
399 end | |
400 return line | |
401 end | |
402 | |
403 Cheevs.UpdateLine = function(handler, block, line, data) | |
404 local print = B.print('CheevsLine') | |
405 line.progress = 0 | |
406 print(' ', data.objectiveIndex,'|cFF0088FF-|r', data.objectiveType, data.text) | |
407 if data.flags then | |
408 if band(data.flags, 0x00000001) > 0 then | |
409 line.format = "%d/%d" | |
410 line.widget = T.SetWidget(line, data, 'ProgressBar', data.criteriaID) | |
411 line.height = line.widget.height | |
412 elseif band(data.flags, 0x00000002) then | |
413 line.widget = nil | |
414 else | |
415 line.widget = nil | |
416 line.displayColor = 'FFFFFF' | |
417 line.displayText = line.text | |
418 | |
419 end | |
420 else | |
421 | |
422 line.displayText = data.text | |
423 end | |
424 print('line.type =', data.type) | |
425 print(' ** qtyStr:', data.quantityString, 'qty:', data.quantity, 'assetID:', data.assetID) | |
426 end | |
427 Default.UpdateLine = function(block, line) | |
428 if line.finished then | |
429 line.progress = 2 | |
430 elseif line.quantity > 0 then | |
431 line.progress = 1 | |
432 else | |
433 line.progress = 0 | |
434 end | |
435 return line | |
436 end | |
437 | |
438 | |
439 T.Quest.numButtons = 0 | |
440 local usedButtons = T.Quest.itemButtons | |
441 local freeButtons = T.Quest.freeButtons | |
442 --[=[ | |
443 T.UpdateWrapper = function(reason) | |
444 print('|cFF00FFFFUpdateWrapper:|r', reason) | |
445 unitLevel = UnitLevel('player') | |
446 wrapperWidth = T.Conf.Wrapper.WrapperWidth | |
447 scrollWidth = T.Conf.Wrapper.WrapperWidth | |
448 local wrapperBlocks = 0 | |
449 -- Update scroll child vertical size | |
450 scrollHeight = 0 | |
451 for i, handler in ipairs(orderedHandlers) do | |
452 T.UpdateTracker(handler) | |
453 local frame = handler.frame | |
454 if handler.actualBlocks >= 1 then | |
455 frame:SetParent(Scroll) | |
456 frame:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) | |
457 frame:SetSize(wrapperWidth, frame.height) | |
458 print('|cFF00FFFF'..frame:GetName()..'|r h:|cFF00FF00', frame.height, '|r y:|cFF00FF00', -scrollHeight) | |
459 scrollHeight = scrollHeight + frame.height | |
460 frame:Show() | |
461 else | |
462 frame:Hide() | |
463 end | |
464 wrapperBlocks = wrapperBlocks + handler.actualBlocks | |
465 end | |
466 print('final scrollHeight:', scrollHeight) | |
467 | |
468 | |
469 | |
470 -- Update frame dimensions | |
471 if scrollHeight > wrapperMaxHeight then | |
472 print(' is larger than', wrapperMaxHeight) | |
473 wrapperHeight = wrapperMaxHeight | |
474 else | |
475 wrapperHeight = scrollHeight | |
476 B.Conf.ObjectiveScroll = 0 | |
477 end | |
478 scrollWidth = floor(scrollWidth+.5) | |
479 scrollHeight = floor(scrollHeight+.5) | |
480 wrapperWidth = floor(wrapperWidth+.5) | |
481 wrapperHeight = floor(wrapperHeight+.5) | |
482 headerHeight = floor(headerHeight+.5) | |
483 | |
484 if wrapperBlocks >= 1 then | |
485 for i, region in ipairs(Wrapper.headerComplex) do | |
486 region:Show() | |
487 end | |
488 else | |
489 for i, region in ipairs(Wrapper.headerComplex) do | |
490 region:Hide() | |
491 end | |
492 return | |
493 end | |
494 --[[wrapperHeight = scrollHeight | |
495 | |
496 print('|cFFFFFF00params:|r scroller:', scrollWidth .. ',' .. scrollHeight, 'scroll:', scrollWidth .. ',' .. scrollHeight, | |
497 'wrapper:', wrapperWidth .. ',' .. wrapperHeight, | |
498 'header:', headerHeight)]] | |
499 | |
500 --Scroller:SetSize(wrapperWidth, wrapperHeight) | |
501 Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, 0) | |
502 Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT') | |
503 | |
504 | |
505 Scroll:SetSize(scrollWidth, scrollHeight) | |
506 Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, B.Conf.ObjectiveScroll or 0) | |
507 Scroll:SetPoint('RIGHT', Scroller, 'RIGHT') | |
508 | |
509 --Scroller:UpdateScrollChildRect() | |
510 Wrapper:SetSize(wrapperWidth, wrapperHeight) | |
511 | |
512 --[[ update action buttons | |
513 print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(), | |
514 '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(), | |
515 '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(), | |
516 '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5) | |
517 ) | |
518 --]] | |
519 T.UpdateActionButtons() | |
520 | |
521 end | |
522 --]=] | |
523 | |
524 | |
525 Default.Update = function (self, reason, ...) | |
526 local print = tprint | |
527 local tracker = self.frame | |
528 local blockIndex = 0 | |
529 local trackerHeight = floor(tracker.titlebg:GetHeight()+.5) | |
530 | |
531 self.currentAnchor = tracker.titlebg | |
532 local numWatched = self:GetNumWatched() | |
533 local numBlocks = self.numBlocks | |
534 local actualBlocks = 0 | |
535 for watchIndex = 1, 25 do | |
536 blockIndex = blockIndex + 1 | |
537 if watchIndex <= numWatched then | |
538 local info = self:GetInfo(watchIndex) | |
539 if info then | |
540 local currentBlock = self:UpdateBlock(blockIndex, info) | |
541 currentBlock:SetPoint('TOPLEFT', self.currentAnchor, 'BOTTOMLEFT', 0, 0) | |
542 currentBlock:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) | |
543 self.currentAnchor = currentBlock | |
544 print(' |cFFFFFF00'..watchIndex..'|r', '|cFF00FF00'..currentBlock:GetName()..'|r', currentBlock.height, trackerHeight) | |
545 trackerHeight = trackerHeight + currentBlock.height | |
546 numBlocks = max(numBlocks, watchIndex) | |
547 actualBlocks = actualBlocks + 1 | |
548 else | |
549 print(' |cFFFF0000bad GetInfo data for #'..watchIndex) | |
550 end | |
551 | |
552 elseif watchIndex <= numBlocks then | |
553 local used = self.usedBlocks | |
554 local free = self.freeBlocks | |
555 print('clean up dead quest block') | |
556 if used[blockIndex] then | |
557 used[blockIndex]:Hide() | |
558 used[blockIndex]:ClearAllPoints() | |
559 free[#free+1]= used[blockIndex] | |
560 used[blockIndex] = nil | |
561 end | |
562 else | |
563 print(' |cFFFF9900END|r @', blockIndex) | |
564 break -- done with quest stuff | |
565 end | |
566 end | |
567 self.numWatched = numWatched | |
568 self.numBlocks = numBlocks | |
569 self.actualBlocks = actualBlocks | |
570 | |
571 tracker.previousHeight = tracker.height | |
572 if numBlocks >= 1 then | |
573 previousBlock = nil | |
574 | |
575 tracker.height = trackerHeight | |
576 tracker:SetHeight(tracker.height) | |
577 tracker:Show() | |
578 | |
579 | |
580 else | |
581 tracker.height = 0 | |
582 tracker:Hide() | |
583 end | |
584 | |
585 return tracker.numWatched, tracker.numAll | |
586 end | |
587 | |
588 --- Updates the selected block frame to display the given info batch | |
589 -- If `previousBlock` is set, it will attempt to anchor to that | |
590 -- @param blockNum the ordered block to be updated, not a watchIndex value | |
591 -- @param info the reference returned by the GetXInfo functions | |
592 -- REMEMBER: t.info and questData[questID] are the same table | |
593 Default.UpdateBlock = function (handler, blockIndex, info) | |
594 local print = bprint | |
595 print(' Read list item |cFF00FFFF'..blockIndex..'|r') | |
596 if not blockIndex or not info then | |
597 return | |
598 end | |
599 local frame = handler.frame | |
600 local block = T.GetBlock(handler, blockIndex) | |
601 block.handler = handler | |
602 block.info = info | |
603 block.mainStyle = info.mainStyle or 'Normal' | |
604 block.subStyle = info.subStyle | |
605 | |
606 info.blockIndex = blockIndex | |
607 if info.questID then handler.QuestBlock[info.questID] = block end | |
608 if info.questLogIndex then handler.LogBlock[info.questLogIndex] = block end | |
609 if info.watchIndex then handler.WatchBlock[info.watchIndex] = block end | |
610 handler.BlockInfo[blockIndex] = info | |
611 | |
612 block.endPoint = block.titlebg | |
613 block.attachmentHeight = 0 | |
614 handler:UpdateObjectives(block) | |
615 | |
616 block.title:SetText(info.title) | |
617 local titleHeight = floor(block.title:GetHeight()+.5) | |
618 local statusHeight = floor(block.status:GetHeight()+.5) | |
619 local attachmentHeight =floor(block.attachmentHeight + .5) | |
620 local titlebgHeight = titleHeight + titleSpacing*2 | |
621 local statusbgHeight = statusHeight + textSpacing*2 | |
622 | |
623 block.titlebg:SetHeight(titlebgHeight) | |
624 | |
625 | |
626 print(' |cFF0088FFanchor to', handler.currentAnchor:GetName()) | |
627 | |
628 print(' |cFF00FF00total sizes:') | |
629 print(' attachment:', attachmentHeight) | |
630 print(' title:', titlebgHeight, '('.. titleHeight..')') | |
631 --block.titlebg:SetHeight(block.title:GetHeight() + T.Conf.Wrapper.TitleSpacing) | |
632 block.height = titlebgHeight + attachmentHeight | |
633 if statusHeight > 1 then | |
634 block.height = block.height + statusbgHeight | |
635 print(' status:', statusbgHeight, '('.. statusHeight..')') | |
636 else | |
637 print(' |cFFFF0088 skipped') | |
638 end | |
639 block:SetHeight(block.height) | |
640 | |
641 print(' |cFFFFFF00height|r:', block.height) | |
642 print(' |cFF00FFFF)|r -> ', block, block:GetHeight()) | |
643 | |
644 block:Show() | |
645 | |
646 if info.specialItem and not info.itemButton then | |
647 print(' - |cFF00FFFFgenerating item button for info set') | |
648 info.itemButton = T.SetItemButton(block, info) | |
649 else | |
650 --info.itemButton = nil | |
651 end | |
652 | |
653 local tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', block, 'TOPRIGHT' | |
654 if info.rewardInfo then | |
655 print('has immediate reward') | |
656 if info.rewardInfo[1].type == 'currency' or info.rewardInfo[1].type == 'item' then | |
657 block.icon:Show() | |
658 block.iconLabel:SetText(info.rewardInfo[1].count) | |
659 block.icon:SetPoint(tagPoint, tagAnchor, tagRelative, -2, -2) | |
660 tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', block.icon, 'TOPLEFT' | |
661 block.icon:SetTexture(info.rewardInfo[1].texture) | |
662 end | |
663 else | |
664 block.icon:Hide() | |
665 end | |
666 | |
667 if info.selected then | |
668 block.SelectionOverlay:Show() | |
669 else | |
670 block.SelectionOverlay:Hide() | |
671 end | |
672 -- workaround for scrollchild issue where layers fall out of sync: in this case, it's by 1 vertical pixel | |
673 --block.highlight:SetPoint('TOPLEFT', block, 'TOPLEFT', 0, 1) | |
674 --block.lowlight:SetPoint('BOTTOMLEFT', block, 'BOTTOMLEFT', 0, 1) | |
675 | |
676 tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative) | |
677 tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative) | |
678 tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative) | |
679 | |
680 return block | |
681 end | |
682 ---------- | |
683 --- Top level methods | |
684 | |
685 local tick = 0 | |
686 function T:Update (reason, ...) | |
687 tick = tick + 1 | |
688 local print = tprint | |
689 reason = reason or OBJECTIVE_TRACKER_UPDATE_REASON | |
690 local updateWrapper = 0 | |
691 local hasStuff | |
692 local insertingStuff | |
693 | |
694 print(format('%d |cFFFF%04X Update()', tick, lshift(reason, 4)), reason, ...) | |
695 currentPosition = 0 | |
696 anchorPoint = 'TOP' | |
697 anchorFrame = Scroll | |
698 | |
699 local wrapperHeight = 0 | |
700 for id, handler in pairs(T.orderedHandlers) do | |
701 local frame = handler.frame | |
702 | |
703 print(format('|cFF00FFFF%s and(%04X vs %04x+%04x) = %04X|r', handler.name, reason, handler.updateReasonModule, handler.updateReasonEvents, band(reason, handler.updateReasonModule + handler.updateReasonEvents))) | |
704 if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then | |
705 handler:Update(reason, ...) | |
706 print(' |cFF00FF00'..id..'|r', handler.displayName, 'count:', handler.numWatched) | |
707 insertingStuff = true | |
708 else | |
709 print(' |cFFFF0088'..id..'|r', 'no reason to update') | |
710 end | |
711 | |
712 if handler.numWatched >= 1 then | |
713 hasStuff = true | |
714 currentPosition = currentPosition + 1 | |
715 frame:SetParent(Scroll) | |
716 frame:SetPoint('TOP', anchorFrame, anchorPoint, 0, 0) | |
717 print(' |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint) | |
718 anchorFrame = handler.frame | |
719 anchorPoint = 'BOTTOM' | |
720 | |
721 print('current frame height:', frame.height) | |
722 wrapperHeight = wrapperHeight + frame.height | |
723 print('|cFFFF0088total height:', wrapperHeight) | |
724 else | |
725 handler.frame:Hide() | |
726 end | |
727 end | |
728 | |
729 | |
730 if hasStuff or insertingStuff then | |
731 print('updating height to', wrapperHeight) | |
732 Wrapper:SetHeight(wrapperHeight) | |
733 Scroller:SetHeight(wrapperHeight) | |
734 Scroll:SetHeight(wrapperHeight) | |
735 Scroller:SetVerticalScroll(B.Conf.ObjectiveScroll or 0) | |
736 print('|cFFFF8800Wrapper:', Wrapper:GetSize()) | |
737 for i = 1, Wrapper:GetNumPoints() do | |
738 print(' ', Wrapper:GetPoint(i)) | |
739 end | |
740 print(' |cFF00FFFFScroller:', Scroller:GetSize()) | |
741 for i = 1, Scroller:GetNumPoints() do | |
742 print(' ', Scroller:GetPoint(i)) | |
743 end | |
744 print(' |cFF00FFFFScroll:', Scroll:GetSize()) | |
745 for i = 1, Scroll:GetNumPoints() do | |
746 print(' ', Scroll:GetPoint(i)) | |
747 end | |
748 | |
749 Wrapper:Show() | |
750 Scroller:Show() | |
751 Scroll:Show() | |
752 end | |
753 Quest.GetClosest() | |
754 | |
755 end | |
756 | |
757 --- Queue any active item buttons for update for that frame | |
758 T.UpdateActionButtons = function(updateReason) | |
759 Scroller.snap_upper = 0 | |
760 Scroller.snap_lower = 0 | |
761 local print = B.print('ItemButton') | |
762 if updateReason then | |
763 print = B.print('IB_'..updateReason) | |
764 end | |
765 | |
766 local previousItem | |
767 for questID, itemButton in pairs(usedButtons) do | |
768 local info= T.Quest.Info[questID] | |
769 | |
770 print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) | |
771 local block = T.Quest.QuestBlock[questID] | |
772 if block then | |
773 -- Dispatch the probe | |
774 if IsQuestWatched(info.questLogIndex) then | |
775 itemButton.previousItem = previousItem | |
776 print(' |cFFFFFF00probing', block:GetName()) | |
777 block:SetScript('OnUpdate', function() | |
778 if block:GetBottom() and not InCombatLockdown() then | |
779 print(' '..block:GetName()..' |cFF00FF00probe hit!') | |
780 T.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope | |
781 block:SetScript('OnUpdate', nil) | |
782 | |
783 end | |
784 end) | |
785 previousItem = itemButton | |
786 else | |
787 print('hidden block or unwatched quest') | |
788 itemButton.previousItem = nil | |
789 itemButton:Hide() | |
790 end | |
791 elseif itemButton:IsVisible() then | |
792 print(' |cFFFF0088hiding unwatched quest button', itemButton:GetName()) | |
793 itemButton.previousItem = nil | |
794 itemButton:Hide() | |
795 else | |
796 print(' |cFFBBBBBBignoring hidden log quest button', itemButton:GetName()) | |
797 end | |
798 end | |
799 end | |
800 | |
801 T.UpdateBlockAction = function (block, itemButton) | |
802 print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()') | |
803 if itemButton.questID ~= block.info.questID then | |
804 print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID) | |
805 -- something happened between this and last frame, go back and set new probes | |
806 return T.UpdateActionButtons() | |
807 end | |
808 | |
809 local previousItem = itemButton.previousItem | |
810 local upper_bound = Scroller:GetTop() + Scroller.snap_upper | |
811 local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize | |
812 local point, anchor, relative | |
813 | |
814 if block:GetBottom() < lower_bound then | |
815 print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5)) | |
816 if previousItem then | |
817 print('adjusting', previousItem:GetName()) | |
818 previousItem:ClearAllPoints() | |
819 previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing) | |
820 end | |
821 itemButton:ClearAllPoints() | |
822 itemButton.x = Wrapper:GetLeft() -4 | |
823 itemButton.y = Wrapper:GetBottom() | |
824 point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT' | |
825 Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing | |
826 | |
827 elseif block:GetTop() > upper_bound then | |
828 print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5)) | |
829 itemButton:ClearAllPoints() | |
830 if previousItem then | |
831 print('latch onto another piece') | |
832 point, anchor, relative ='TOP', previousItem, 'BOTTOM' | |
833 itemButton.x = 0 | |
834 itemButton.y = -itemButtonSpacing | |
835 else | |
836 print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop()) | |
837 point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' | |
838 itemButton.x = Scroller:GetLeft() -4 | |
839 itemButton.y = Scroller:GetTop() | |
840 end | |
841 itemButton:Show() | |
842 Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing) | |
843 else | |
844 print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5)) | |
845 itemButton:ClearAllPoints() | |
846 itemButton.x = block:GetLeft() - itemButtonSpacing | |
847 itemButton.y = block:GetTop() | |
848 point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' | |
849 end | |
850 | |
851 itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y) | |
852 itemButton:Show() | |
853 end | |
854 | |
855 T.UpdateItemButtonCooldown = function(button) | |
856 | |
857 end | |
858 | |
859 local unitLevel = UnitLevel('player') | |
860 | |
861 |