annotate ObjectiveFrame.lua @ 22:9b3fa734abff

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