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 |
