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