annotate ObjectiveFrame.lua @ 6:589de8ea05b9

- validate tracked objects' existence by use of those handler.Info tables we made - apply collision checking to action buttons when their corresponding entry has scrolled out
author Nenue
date Fri, 01 Apr 2016 01:30:42 -0400
parents e9b61fd5f607
children 5301c68f28d8
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@2 7 local ipairs, max, min, unpack, floor, pairs, tostring, type = ipairs, max, min, unpack, floor, pairs, tostring, type
Nenue@2 8 local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion
Nenue@2 9 local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent
Nenue@1 10 local CreateFrame = CreateFrame
Nenue@1 11 local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
Nenue@1 12 local print = B.print('Objectives')
Nenue@1 13 --------------------------------------------------------------------
Nenue@1 14 --- Global frame layout
Nenue@1 15 --------------------------------------------------------------------
Nenue@1 16
Nenue@1 17 --- Upvalues
Nenue@2 18 local Wrapper = VeneerObjectiveWrapper
Nenue@1 19 local Scroller = Wrapper.scrollArea
Nenue@2 20 local Scroll = VeneerObjectiveScroll
Nenue@1 21 local orderedHandlers = mod.orderedHandlers
Nenue@1 22 local orderedNames = mod.orderedNames
Nenue@1 23
Nenue@1 24 --- Temp values set during updates
Nenue@1 25 local wrapperWidth, wrapperHeight
Nenue@1 26 local scrollWidth, scrollHeight
Nenue@1 27 local previousBlock
Nenue@1 28 local currentBlock
Nenue@1 29 --- todo: map these into config table when its sorted out
Nenue@6 30 local itemButtonSize, itemButtonSpacing = 36, 1
Nenue@1 31 local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]]
Nenue@1 32 local titleSize, textSize = 15, 15
Nenue@1 33 local titleOutline, textOutline = "OUTLINE", "OUTLINE"
Nenue@1 34 local titleSpacing, textSpacing = 4, 3
Nenue@1 35 local textIndent = 5
Nenue@1 36 local wrapperMaxWidth, wrapperMaxHeight = 280, 490 -- these are the hard bounds, actual *Height variables are changed
Nenue@2 37 local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE'
Nenue@1 38 local headerFont, headerSize, headerHeight = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 18, 24
Nenue@2 39 local headerOutline, headerColor, headerSpacing = 'OUTLINE', {1,1,1,1}, 2
Nenue@1 40 local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0}
Nenue@1 41
Nenue@2 42 --- These are mostly aesthetic choices so it lives here
Nenue@1 43 mod.defaults = {
Nenue@1 44 ObjectiveTrackerAnchor = {'BOTTOM', 'RIGHT'},
Nenue@1 45 ObjectiveTrackerParent = 'DebuffButton',
Nenue@1 46 ObjectiveTrackerSize = {250, 600},
Nenue@1 47 ObjectiveWrapperParent = '',
Nenue@2 48 WrapperStyle = {
Nenue@2 49 Header = {
Nenue@6 50 Background = {Left = '', Right = '', Tile = ''},
Nenue@2 51 BackgroundCrop = {Left = {0, 0.4, 0,1}, Right={0.6,1,0,1}, Tile = {0.4,.6,0,1,}},
Nenue@2 52 BackgroundScale = {Left = 100, Right = 100},
Nenue@2 53 Font = {wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline}
Nenue@2 54 }
Nenue@2 55 },
Nenue@2 56 ObjectiveHeaderStyle = {
Nenue@2 57 Normal = {
Nenue@6 58 Gradient = {MinColor = {.05,.15,0.5,0.7}, MaxColor = {.05,.15,0.5,.35}},
Nenue@2 59 Font = {headerFont, headerSize, headerOutline}, Spacing = headerSpacing,
Nenue@2 60 }
Nenue@2 61 },
Nenue@1 62 ObjectiveTrackerStyle = {
Nenue@1 63 Normal = {
Nenue@1 64 Title = {
Nenue@6 65 Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, .19}},
Nenue@1 66 Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing,
Nenue@1 67 },
Nenue@1 68 Text = {
Nenue@6 69 Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, .12}},
Nenue@1 70 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
Nenue@1 71 },
Nenue@1 72 },
Nenue@1 73 Super = {
Nenue@1 74 Title = {
Nenue@1 75 Gradient = { MinColor = {0, .7, .6, .8}, MaxColor = {0, .7, .6, 0.2}},
Nenue@1 76 Font = {titleFont, titleSize, titleOutline},
Nenue@1 77 Spacing = titleSpacing, BackgroundFullWidth = true
Nenue@1 78 },
Nenue@1 79 Text = {
Nenue@1 80 Gradient = { MinColor = {0, .7, .6, 0.5}, MaxColor = {0, .7, .6, 0.1} },
Nenue@1 81 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
Nenue@1 82 },
Nenue@1 83 },
Nenue@1 84 Active = {
Nenue@1 85 Title = {
Nenue@1 86 Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, },
Nenue@1 87 Font = {titleFont, titleSize, titleOutline},
Nenue@1 88 Spacing = titleSpacing,
Nenue@1 89 BackgroundFullWidth = true
Nenue@1 90 },
Nenue@1 91 Text = {
Nenue@1 92 Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, },
Nenue@1 93 Font = {textFont, textSize, textOutline},
Nenue@1 94 Spacing = textSpacing,
Nenue@1 95 BackgroundFullWidth = true
Nenue@1 96 }
Nenue@1 97 },
Nenue@1 98 Complete = {
Nenue@1 99 Title = {
Nenue@1 100 Gradient = { MinColor = {0, 1, 0, 0.34}, MaxColor = {0, 1, 0, .17}, },
Nenue@1 101 Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing,
Nenue@1 102 BackgroundFullWidth = true
Nenue@1 103 },
Nenue@1 104 Text = {
Nenue@1 105 Gradient = { MinColor = {0, 1, 0, .25}, MaxColor = {0, 1, 0, 0.12}, },
Nenue@1 106 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
Nenue@1 107 BackgroundFullWidth = true
Nenue@1 108 }
Nenue@1 109 },
Nenue@1 110 }
Nenue@1 111 }
Nenue@1 112
Nenue@3 113 local FontBank = {
Nenue@3 114 ['Normal'] = VeneerCriteriaFontNormal,
Nenue@3 115 ['Progress'] = VeneerCriteriaFontProgress,
Nenue@3 116 ['Complete'] = VeneerCriteriaFontComplete,
Nenue@3 117 ['Failed'] = VeneerCriteriaFontFailed,
Nenue@3 118 }
Nenue@3 119
Nenue@2 120 local Scroller_OnShow = function()
Nenue@2 121 Wrapper.watchMoneyReasons = 0;
Nenue@2 122 mod.UpdateWrapper()
Nenue@2 123 mod.SetEvents()
Nenue@2 124 for i, region in ipairs(Wrapper.header) do
Nenue@2 125 region:Show()
Nenue@2 126 end
Nenue@2 127 end
Nenue@2 128
Nenue@2 129 local Scroller_OnHide = function()
Nenue@2 130 local self = Wrapper
Nenue@2 131 Wrapper:UnregisterAllEvents()
Nenue@2 132 Wrapper:SetScript('OnEvent', nil)
Nenue@2 133 for i, region in ipairs(Wrapper.header) do
Nenue@2 134 region:Hide()
Nenue@2 135 end
Nenue@2 136 end
Nenue@2 137
Nenue@2 138 local Scroller_OnMouseWheel = function(self, delta)
Nenue@2 139 local r = Scroll:GetHeight() - Scroller:GetHeight()
Nenue@2 140 local s = self:GetVerticalScroll() - delta * floor(r/5+.5)
Nenue@2 141 if r == 0 then return end
Nenue@2 142 if s >= r then
Nenue@2 143 s = r
Nenue@2 144 elseif s < 1 then
Nenue@2 145 s = 0
Nenue@2 146 end
Nenue@2 147 self:SetVerticalScroll(s)
Nenue@2 148 print(s, r, self:GetVerticalScroll())
Nenue@2 149
Nenue@6 150 mod.UpdateActionButtons('SCROLLING')
Nenue@2 151 end
Nenue@2 152
Nenue@2 153 local WrapperCloseButton_OnClick = function(self)
Nenue@2 154 if Scroller:IsVisible() then
Nenue@2 155 Scroller:Hide()
Nenue@2 156 else
Nenue@2 157 Scroller:Show()
Nenue@2 158 end
Nenue@2 159 end
Nenue@2 160
Nenue@2 161 mod.InitializeTrackers = function()
Nenue@2 162
Nenue@2 163 local c = mod.defaults.ObjectiveHeaderStyle.Normal
Nenue@2 164 local g1, g2, g3, g4 = unpack(c.Gradient.MinColor)
Nenue@2 165 local h1, h2, h3, h4 = unpack(c.Gradient.MaxColor)
Nenue@2 166
Nenue@2 167 for i, name in ipairs(orderedNames) do
Nenue@2 168 if not mod.orderedHandlers[i] then
Nenue@2 169 if mod.Tracker(name, i) then
Nenue@2 170 local handler = mod[name]
Nenue@2 171
Nenue@2 172 local tracker = CreateFrame('Frame', 'Veneer'..name..'Tracker', Scroll, 'VeneerTrackerTemplate')
Nenue@2 173 tracker.header:SetText(handler.name)
Nenue@2 174 tracker.header:SetHeight(headerHeight)
Nenue@2 175 tracker.header:SetFont(unpack(c.Font))
Nenue@2 176 tracker.header:SetTextColor(unpack(headerColor))
Nenue@2 177
Nenue@2 178 tracker.headerbg:SetGradientAlpha('HORIZONTAL', g1, g2 ,g3, g4, h1, h2, h3, h4)
Nenue@2 179 tracker.headerbg:SetHeight(headerHeight)
Nenue@2 180
Nenue@2 181 handler.Tracker = tracker
Nenue@2 182 mod.orderedTrackers[i] = tracker
Nenue@2 183 mod.namedTrackers[name] = tracker
Nenue@2 184 mod.indexedTrackers[handler] = tracker
Nenue@2 185 print('created new tracker frames for new handler')
Nenue@2 186 end
Nenue@2 187 end
Nenue@2 188 end
Nenue@2 189
Nenue@2 190 Scroller:SetScrollChild(Scroll)
Nenue@2 191 Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel)
Nenue@2 192 Scroller:SetScript('OnShow', Scroller_OnShow)
Nenue@2 193 Scroller:SetScript('OnHide', Scroller_OnHide)
Nenue@2 194 Wrapper.close:SetScript('OnClick', WrapperCloseButton_OnClick)
Nenue@2 195 Wrapper:SetPoint(unpack(wrapperPosition))
Nenue@2 196 Scroller_OnShow(Scroller)
Nenue@2 197
Nenue@2 198 mod.UpdateWrapperStyle()
Nenue@2 199 end
Nenue@2 200
Nenue@2 201 mod.InitializeXPTracker = function()
Nenue@2 202 local XPBar = Wrapper.XPBar
Nenue@2 203 if UnitLevel('player') == 100 then
Nenue@2 204 XPBar:Hide()
Nenue@2 205 return
Nenue@2 206 end
Nenue@2 207
Nenue@2 208 --- xp bar
Nenue@6 209 XPBar:SetWidth(wrapperWidth - Wrapper.close:GetWidth())
Nenue@6 210 XPBar.bg:SetAllPoints(XPBar)
Nenue@6 211 XPBar:RegisterEvent('DISABLE_XP_GAIN')
Nenue@6 212 XPBar:RegisterEvent('ENABLE_XP_GAIN')
Nenue@2 213 XPBar:SetScript('OnEvent', mod.UpdateXP)
Nenue@6 214
Nenue@6 215 if not IsXPUserDisabled() then
Nenue@6 216 mod.EnableXP(XPBar)
Nenue@6 217 else
Nenue@6 218 mod.DisableXP(XPBar)
Nenue@6 219 end
Nenue@6 220
Nenue@6 221 mod.UpdateXP(XPBar)
Nenue@2 222 end
Nenue@2 223
Nenue@6 224 mod.EnableXP = function(self)
Nenue@6 225 self:RegisterEvent('PLAYER_XP_UPDATE')
Nenue@6 226 self:RegisterEvent('PLAYER_LEVEL_UP')
Nenue@6 227 self:RegisterEvent('PLAYER_UPDATE_RESTING')
Nenue@6 228 self.bg:SetTexture(0,0,0,.25)
Nenue@6 229 self:Show()
Nenue@6 230 end
Nenue@2 231
Nenue@6 232 mod.DisableXP = function(self)
Nenue@6 233 self:UnregisterEvent('PLAYER_XP_UPDATE')
Nenue@6 234 self:UnregisterEvent('PLAYER_LEVEL_UP')
Nenue@6 235 self:UnregisterEvent('PLAYER_UPDATE_RESTING')
Nenue@6 236 self.bg:SetTexture(0.5,0.5,0.5,0.5)
Nenue@6 237 self:Hide()
Nenue@6 238 end
Nenue@2 239
Nenue@6 240 mod.UpdateXP = function(self, event)
Nenue@6 241 if event == 'DISABLE_XP_GAIN' then
Nenue@6 242 mod.DisableXP(self)
Nenue@6 243 elseif event == 'ENABLE_XP_GAIN' then
Nenue@6 244 mod.EnableXP(self)
Nenue@2 245 end
Nenue@2 246
Nenue@6 247 if not IsXPUserDisabled() then
Nenue@6 248
Nenue@6 249 local xp = UnitXP('player')
Nenue@6 250 local xpmax = UnitXPMax('player')
Nenue@6 251 local rest = GetXPExhaustion()
Nenue@6 252 self.fg:SetWidth((xp/xpmax) * self:GetWidth())
Nenue@6 253 if rest then
Nenue@6 254 self.rested:ClearAllPoints()
Nenue@6 255 if xp == 0 then
Nenue@6 256 self.rested:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
Nenue@6 257 else
Nenue@6 258 self.rested:SetPoint('TOPLEFT', self.fg, 'TOPRIGHT', 0, 0)
Nenue@6 259 end
Nenue@6 260
Nenue@6 261 if (xp + rest) > xpmax then
Nenue@6 262 self.rested:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, 0)
Nenue@6 263 else
Nenue@6 264 self.rested:SetWidth((rest/xpmax) * self:GetWidth())
Nenue@6 265 end
Nenue@6 266 self.rested:SetPoint('BOTTOM', self, 'BOTTOM')
Nenue@6 267 self.rested:Show()
Nenue@2 268 else
Nenue@6 269 self.rested:Hide()
Nenue@2 270 end
Nenue@2 271
Nenue@6 272 if IsResting() then
Nenue@6 273 self.bg:SetTexture(.2,.8,.2,.5)
Nenue@2 274 else
Nenue@6 275 self.bg:SetTexture(0,0,0,.25)
Nenue@2 276 end
Nenue@6 277 self.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or ''))
Nenue@2 278 end
Nenue@2 279 end
Nenue@2 280
Nenue@2 281 mod.UpdateReputation = function(self)
Nenue@2 282 end
Nenue@1 283
Nenue@1 284 --- Argument containers
Nenue@1 285 local a1, a2, a3, a4, b1, b2, b3, b4, f1, f2, f3, w1, w2
Nenue@1 286 mod.SetBlockStyle = function(block, name)
Nenue@1 287 -- var names intended to reflect argument order
Nenue@2 288 --@debug@
Nenue@1 289 local c = mod.defaults.ObjectiveTrackerStyle[name]
Nenue@2 290 --@end-debug@
Nenue@2 291 --[===[@non-debug
Nenue@2 292 local c = mod.Conf
Nenue@2 293 --@end-non-debug]===]
Nenue@1 294 a1, a2, a3, a4 = unpack(c.Title.Gradient.MinColor)
Nenue@1 295 b1, b2, b3, b4 = unpack(c.Title.Gradient.MaxColor)
Nenue@1 296 block.titlebg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4)
Nenue@1 297
Nenue@1 298 a1, a2, a3, a4 = unpack(c.Text.Gradient.MinColor)
Nenue@1 299 b1, b2, b3, b4 = unpack(c.Text.Gradient.MaxColor)
Nenue@1 300 block.bg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4)
Nenue@1 301
Nenue@1 302 f1, f2, f3 = unpack(c.Title.Font)
Nenue@1 303 block.title:SetFont(f1, f2, f3)
Nenue@1 304
Nenue@1 305 f1, f2 ,f3 = unpack(c.Text.Font)
Nenue@1 306 block.objectives:SetFont(f1,f2,f3)
Nenue@1 307
Nenue@1 308 w1 = Wrapper:GetWidth()
Nenue@1 309 w2 = (c.Title.BackgroundFullWidth and w1 or block.title:GetStringWidth())
Nenue@1 310
Nenue@1 311 local titleSpacing, titleSpacing2 = c.Title.Spacing, (c.Title.Spacing * 2)
Nenue@1 312 local textSpacing, textSpacing2 = c.Text.Spacing, (c.Text.Spacing * 2)
Nenue@1 313
Nenue@1 314 if block.info.isTrivial then
Nenue@1 315 block.title:SetTextColor(0.7, 0.7, 0.7, 1)
Nenue@1 316 elseif block.info.isComplete then
Nenue@1 317 block.title:SetTextColor(1,1,1,1)
Nenue@1 318 else
Nenue@1 319 block.title:SetTextColor(0,.7,1,1)
Nenue@1 320 end
Nenue@1 321 block.title:SetSpacing(titleSpacing)
Nenue@1 322 block.objectives:SetSpacing(textSpacing)
Nenue@1 323 block.objectives:SetWordWrap(true)
Nenue@1 324
Nenue@1 325 local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight()
Nenue@1 326 local blockHeight = titleHeight + titleSpacing2 + textHeight + textSpacing2
Nenue@1 327 local blockWidth = wrapperMaxWidth
Nenue@1 328
Nenue@1 329 block.titlebg:SetSize(min(w1, w2), titleHeight + titleSpacing2)
Nenue@1 330 block.bg:SetSize(w1, textHeight + textSpacing2)
Nenue@1 331 block:SetSize(blockWidth, blockHeight)
Nenue@1 332
Nenue@1 333 block.title:SetPoint('TOPLEFT', block.titlebg, 'TOPLEFT', 0, -titleSpacing)
Nenue@1 334 block.objectives:SetPoint('TOPLEFT', block.titlebg, 'BOTTOMLEFT', textIndent, -textSpacing)
Nenue@1 335
Nenue@1 336 -- store
Nenue@1 337 block.titleHeight = titleHeight
Nenue@1 338 block.textHeight = textHeight
Nenue@1 339 block.width = blockWidth
Nenue@1 340 block.height = blockHeight
Nenue@1 341
Nenue@2 342 print(' |cFF00FFFF'..block:GetName()..'|r:|cFF0088FFSetStyle|r(', blockWidth, 'x', blockHeight, '(textH', textHeight,', titleH', titleHeight, ')')
Nenue@2 343 end
Nenue@2 344
Nenue@2 345 local segments = {'Left', 'Right', 'Tile'}
Nenue@2 346 mod.UpdateWrapperStyle = function()
Nenue@2 347 local c = mod.defaults.WrapperStyle
Nenue@2 348 for _, segment in ipairs(segments) do
Nenue@2 349 Wrapper['Background'..segment]:SetAtlas(c.Header.Background[segment])
Nenue@2 350 Wrapper['Background'..segment]:SetTexCoord(unpack(c.Header.BackgroundCrop[segment]))
Nenue@2 351 if c.Header.BackgroundScale[segment] then
Nenue@2 352 Wrapper['Background'..segment]:SetWidth(c.Header.BackgroundScale[segment])
Nenue@2 353 end
Nenue@2 354 end
Nenue@1 355 end
Nenue@1 356
Nenue@1 357 --- Updates the selected block frame to display the given info batch
Nenue@1 358 -- If `previousBlock` is set, it will attempt to anchor to that
Nenue@1 359 -- @param blockNum the ordered block to be updated, not a watchIndex value
Nenue@1 360 -- @param info the reference returned by the GetXInfo functions
Nenue@1 361 -- REMEMBER: t.info and questData[questID] are the same table
Nenue@1 362 mod.UpdateTrackerBlock = function (handler, blockIndex, info)
Nenue@2 363 print(' |cFF00FFFFUpdateTrackerBlock('..blockIndex..'|r')
Nenue@1 364 if not blockIndex or not info then
Nenue@1 365 return
Nenue@1 366 end
Nenue@1 367
Nenue@1 368 local tracker = handler.Tracker
Nenue@1 369
Nenue@1 370 local t = handler:GetBlock(blockIndex)
Nenue@1 371 if previousBlock then
Nenue@1 372 if blockIndex == 1 then
Nenue@1 373 t:SetPoint('TOPLEFT', previousBlock, 'TOPLEFT', 0, -headerHeight)
Nenue@1 374 else
Nenue@1 375 t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0)
Nenue@1 376 end
Nenue@1 377 t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0)
Nenue@1 378 end
Nenue@2 379 --print(t:GetName(), t:GetSize())
Nenue@2 380 --print(t:GetPoint(1))
Nenue@1 381
Nenue@1 382 t.info = info
Nenue@1 383
Nenue@5 384 if info.questID then handler.QuestBlock[info.questID] = t end
Nenue@1 385 if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end
Nenue@1 386 if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end
Nenue@1 387
Nenue@1 388 info.blockIndex = blockIndex
Nenue@1 389 handler.BlockInfo[blockIndex] = info
Nenue@1 390 t.Select = handler.Select
Nenue@1 391 t.Open = handler.Open
Nenue@1 392 t.Remove = handler.Remove
Nenue@1 393 t.Link = handler.Link
Nenue@1 394 t:SetScript('OnMouseUp', handler.OnMouseUp)
Nenue@1 395 t:SetScript('OnMouseDown', handler.OnMouseDown)
Nenue@1 396 t.title:SetText(info.title)
Nenue@1 397
Nenue@1 398 if info.isComplete then
Nenue@1 399 t.objectives:Show()
Nenue@1 400 t.objectives:SetText(info.completionText)
Nenue@1 401 elseif info.numObjectives >= 1 then
Nenue@1 402 t.objectives:Show()
Nenue@2 403 print(' - objective lines:', info.numObjectives, 'can wrap:', t.objectives:CanWordWrap())
Nenue@3 404
Nenue@1 405 local text = ''
Nenue@3 406 if info.description then
Nenue@3 407 print(' -- has description text:', select('#', info.description), info.description)
Nenue@3 408 text = info.description
Nenue@3 409 end
Nenue@3 410
Nenue@3 411 --- todo: implement objective displays
Nenue@3 412 -- in an accumulator loop, call upon handler for the appropriate display frame, each defining:
Nenue@3 413 -- * height of whatever display widget is involved in conveying the task
Nenue@3 414 -- * number of non-wrapped text lines to account for line space; may be discarded depending on things
Nenue@3 415 -- * boolean that determines listening for money events or not
Nenue@4 416 t.attachmentHeight, text = mod.UpdateObjectives(t, info, text)
Nenue@3 417
Nenue@1 418 t.objectives:SetText(text)
Nenue@3 419 t.objectives:SetWordWrap(true)
Nenue@1 420
Nenue@1 421
Nenue@1 422
Nenue@1 423 elseif info.description then
Nenue@1 424 t.objectives:SetText(info.description)
Nenue@1 425 t.objectives:SetWordWrap(true)
Nenue@1 426 else
Nenue@1 427 t.objectives:SetText(nil)
Nenue@1 428 end
Nenue@1 429 local style = 'Normal'
Nenue@1 430 if info.isComplete then
Nenue@1 431 style = 'Complete'
Nenue@1 432 elseif info.superTracked then
Nenue@1 433 style = 'Super'
Nenue@1 434 end
Nenue@1 435
Nenue@5 436 if info.specialItem and not info.itemButton then
Nenue@5 437 print(' - |cFF00FFFFgenerating item button for info set')
Nenue@4 438 info.itemButton = mod.SetItemButton(t, info)
Nenue@4 439 else
Nenue@4 440 --info.itemButton = nil
Nenue@4 441 end
Nenue@4 442
Nenue@6 443 if Devian and Devian.InWorkspace() then
Nenue@6 444 t.debugText:Show()
Nenue@6 445 t.debugText:SetText(tostring(blockIndex) .. '\n' .. tostring(info.itemButton and info.itemButton:GetName()))
Nenue@6 446 end
Nenue@6 447
Nenue@3 448 --- metrics are calculated in SetStyle
Nenue@1 449 t:SetStyle(style)
Nenue@3 450 t:Show()
Nenue@1 451
Nenue@3 452 print(' |cFF00FFFF)|r -> ', t, t:GetHeight())
Nenue@1 453 return t
Nenue@1 454 end
Nenue@1 455
Nenue@4 456 mod.UpdateObjectives = function(block, info, text)
Nenue@4 457 local attachmentHeight = 0
Nenue@4 458 for o, obj in ipairs(info.objectives) do
Nenue@4 459 --- achievement criteria
Nenue@4 460 if obj.flags then
Nenue@4 461
Nenue@4 462
Nenue@4 463 if bit.band(obj.flags, 0x00000001) > 0 then
Nenue@4 464 obj.type = 'ProgressBar'
Nenue@4 465 obj.widget = mod.SetWidget(obj, info)
Nenue@4 466 elseif bit.band(obj.flags, 0x00000002) then
Nenue@4 467 obj.type = 'Hidden'
Nenue@4 468 obj.widget = nil
Nenue@4 469 else
Nenue@4 470 obj.type = 'Text'
Nenue@4 471 obj.widget = nil
Nenue@4 472 text = text .. ((text == '') and "" or "\n") .. obj.text
Nenue@4 473 end
Nenue@4 474
Nenue@4 475 print(obj.type, obj.text, obj.quantityString)
Nenue@4 476 --- none of the above (most quests)
Nenue@4 477 else
Nenue@4 478 local line = obj.text
Nenue@4 479 local color = '00FFFF'
Nenue@4 480 if obj.finished then
Nenue@4 481 color = 'FFFFFF'
Nenue@4 482 elseif obj.type == 'monster' then
Nenue@4 483 color = 'FFFF00'
Nenue@4 484 elseif obj.type == 'item' then
Nenue@4 485 color = '44DDFF'
Nenue@4 486 elseif obj.type == 'object' then
Nenue@4 487 color = 'FF44DD'
Nenue@4 488 end
Nenue@4 489 text = text .. ((text == '') and "" or "\n") .. '|cFF'..color.. line .. '|r'
Nenue@4 490 end
Nenue@4 491
Nenue@4 492 if obj.widget then
Nenue@4 493 attachmentHeight = attachmentHeight + obj.widget.height
Nenue@4 494 end
Nenue@4 495
Nenue@4 496 end
Nenue@4 497 return attachmentHeight, text
Nenue@4 498 end
Nenue@4 499
Nenue@1 500 mod.UpdateTracker = function(handler)
Nenue@1 501 print('|cFF00FF88UpdateTracker(|r|cFFFF4400' .. type(handler) .. '|r :: |cFF88FFFF' .. tostring(handler) .. '|r')
Nenue@1 502 local tracker = handler.Tracker
Nenue@1 503 local blockIndex = 0
Nenue@1 504 local trackerHeight = headerHeight
Nenue@1 505 local w = 300
Nenue@1 506
Nenue@1 507 previousBlock = handler.Tracker
Nenue@1 508 local numWatched = handler.GetNumWatched()
Nenue@1 509 local numBlocks = handler.numBlocks
Nenue@1 510 local actualBlocks = handler.actualBlocks
Nenue@1 511 for watchIndex = 1, 25 do
Nenue@1 512 blockIndex = blockIndex + 1
Nenue@1 513 if watchIndex <= numWatched then
Nenue@1 514 local info = handler:GetInfo(watchIndex)
Nenue@1 515 if info then
Nenue@1 516 local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info)
Nenue@1 517 previousBlock = currentBlock
Nenue@1 518 trackerHeight = trackerHeight + currentBlock.height
Nenue@1 519 numBlocks = max(numBlocks, watchIndex)
Nenue@1 520 actualBlocks = actualBlocks + 1
Nenue@1 521 else
Nenue@1 522 print('|cFFFF0000Failed to draw info for index #'..watchIndex)
Nenue@1 523 end
Nenue@1 524
Nenue@1 525 elseif watchIndex <= numBlocks then
Nenue@1 526 local used = handler.usedBlocks
Nenue@1 527 local free = handler.freeBlocks
Nenue@1 528 print('clean up dead quest block')
Nenue@1 529 if used[blockIndex] then
Nenue@1 530 used[blockIndex]:Hide()
Nenue@1 531 used[blockIndex]:ClearAllPoints()
Nenue@1 532 free[#free+1]= used[blockIndex]
Nenue@1 533 used[blockIndex] = nil
Nenue@1 534 end
Nenue@1 535 else
Nenue@1 536 print('Stopping scan at', blockIndex)
Nenue@1 537 break -- done with quest stuff
Nenue@1 538 end
Nenue@1 539 end
Nenue@1 540 handler.numWatched = numWatched
Nenue@1 541 handler.numBlocks = numBlocks
Nenue@1 542 handler.actualBlocks = actualBlocks
Nenue@1 543 handler:Report()
Nenue@1 544 previousBlock = nil
Nenue@1 545 if numBlocks > 0 then
Nenue@1 546 tracker.height = trackerHeight
Nenue@1 547 else
Nenue@1 548 tracker.height = 0
Nenue@1 549 end
Nenue@1 550
Nenue@1 551 print('|cFF00FF88)|r ->', numBlocks, 'blocks; height', tracker.height, 'last block: ')
Nenue@1 552 end
Nenue@1 553
Nenue@1 554 mod.Quest.numButtons = 0
Nenue@1 555 local usedButtons = mod.Quest.itemButtons
Nenue@1 556 local freeButtons = mod.Quest.freeButtons
Nenue@1 557 mod.UpdateWrapper = function()
Nenue@1 558 wrapperWidth = wrapperMaxWidth
Nenue@1 559 scrollWidth = wrapperWidth
Nenue@1 560 local wrapperBlocks = 0
Nenue@1 561 -- Update scroll child vertical size
Nenue@1 562 scrollHeight = 0
Nenue@1 563 for i, handler in ipairs(orderedHandlers) do
Nenue@1 564 mod.UpdateTracker(handler)
Nenue@1 565 if handler.actualBlocks >= 1 then
Nenue@1 566 local tracker = handler.Tracker
Nenue@1 567 print('setting', handler.Tracker, 'to anchor to offset', -scrollHeight)
Nenue@1 568 tracker:SetParent(Scroll) -- this doesn't do anything that relativeTo doesn't
Nenue@1 569 tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight)
Nenue@1 570 tracker:SetSize(wrapperWidth, tracker.height)
Nenue@1 571 print('adding ', tracker.height)
Nenue@1 572 scrollHeight = scrollHeight + tracker.height
Nenue@1 573 end
Nenue@1 574 wrapperBlocks = wrapperBlocks + handler.actualBlocks
Nenue@1 575 end
Nenue@1 576 print('final scrollHeight:', scrollHeight)
Nenue@1 577
Nenue@1 578
Nenue@1 579
Nenue@1 580 -- Update frame dimensions
Nenue@1 581 if scrollHeight > wrapperMaxHeight then
Nenue@1 582 print(' is larger than', wrapperMaxHeight)
Nenue@1 583 --ScrollBar:Show()
Nenue@1 584 --scrollWidth = wrapperMaxWidth - scrollBarWidth
Nenue@1 585 wrapperHeight = wrapperMaxHeight
Nenue@1 586 -- Make ThumbTexture reflect the viewing scale (smaller for longer scroll, bigger for shorter)
Nenue@1 587 --ScrollBar:GetThumbTexture():SetHeight((wrapperMaxHeight/scrollHeight) * (wrapperMaxHeight))
Nenue@1 588 --ScrollBar:SetWidth(scrollBarWidth)
Nenue@1 589 --ScrollBar:SetPoint('TOPRIGHT', Scroller, 'TOPRIGHT', 0, 0)
Nenue@1 590 --ScrollBar:SetPoint('BOTTOMLEFT', Scroller, 'BOTTOMRIGHT', -scrollBarWidth, 0)
Nenue@1 591 --ScrollBar:SetMinMaxValues(1, scrollHeight - wrapperMaxHeight)
Nenue@1 592 else
Nenue@1 593 --ScrollBar:Hide()
Nenue@1 594 wrapperHeight = scrollHeight
Nenue@1 595 end
Nenue@1 596 scrollWidth = floor(scrollWidth+.5)
Nenue@1 597 scrollHeight = floor(scrollHeight+.5)
Nenue@1 598 wrapperWidth = floor(wrapperWidth+.5)
Nenue@1 599 wrapperHeight = floor(wrapperHeight+.5)
Nenue@1 600 headerHeight = floor(headerHeight+.5)
Nenue@1 601
Nenue@1 602 if wrapperBlocks >= 1 then
Nenue@2 603 for i, region in ipairs(Wrapper.header) do
Nenue@2 604 region:Show()
Nenue@2 605 end
Nenue@1 606 else
Nenue@2 607 for i, region in ipairs(Wrapper.header) do
Nenue@2 608 region:Hide()
Nenue@2 609 end
Nenue@1 610 return
Nenue@1 611 end
Nenue@1 612 --wrapperHeight = scrollHeight
Nenue@1 613
Nenue@1 614 print('|cFFFFFF00params:|r scroller:', scrollWidth, 'x', scrollHeight)
Nenue@1 615 print('|cFFFFFF00params:|r scroll:', scrollWidth, 'x', scrollHeight)
Nenue@1 616 print('|cFFFFFF00params:|r wrapper:', wrapperWidth, 'x', wrapperHeight)
Nenue@1 617 print('|cFFFFFF00params:|r header:', headerHeight)
Nenue@1 618
Nenue@1 619 Scroller:SetSize(wrapperWidth, wrapperHeight)
Nenue@1 620 Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, -headerHeight)
Nenue@1 621 Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT')
Nenue@1 622
Nenue@1 623 Scroll:SetSize(scrollWidth, scrollHeight)
Nenue@1 624 Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, 0)
Nenue@1 625 Scroll:SetPoint('RIGHT', Scroller, 'RIGHT')
Nenue@1 626
Nenue@1 627 --Scroller:UpdateScrollChildRect()
Nenue@1 628 Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight)
Nenue@1 629
Nenue@1 630 -- update action buttons
Nenue@6 631 print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(),
Nenue@6 632 '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(),
Nenue@6 633 '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(),
Nenue@6 634 '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5)
Nenue@6 635 )
Nenue@6 636 mod.UpdateActionButtons('FULL_UPDATE')
Nenue@1 637
Nenue@6 638 QuestPOIUpdateIcons()
Nenue@1 639 end
Nenue@1 640
Nenue@1 641 --- Queue any active item buttons for update for that frame
Nenue@6 642 mod.UpdateActionButtons = function(updateReason)
Nenue@6 643 Scroller.snap_upper = 0
Nenue@6 644 Scroller.snap_lower = 0
Nenue@6 645 local print = B.print('ItemButton')
Nenue@6 646 if updateReason then
Nenue@6 647 print = B.print('IB_'..updateReason)
Nenue@6 648 end
Nenue@6 649
Nenue@1 650 local previousItem
Nenue@2 651 for questID, itemButton in pairs(usedButtons) do
Nenue@6 652 local info= mod.Quest.Info[questID]
Nenue@6 653
Nenue@5 654 print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName())
Nenue@5 655 local block = mod.Quest.QuestBlock[questID]
Nenue@1 656 if block then
Nenue@5 657 -- Dispatch the probe
Nenue@6 658 if IsQuestWatched(info.questLogIndex) then
Nenue@6 659 itemButton.previousItem = previousItem
Nenue@5 660 print(' |cFFFFFF00probing', block:GetName())
Nenue@1 661 block:SetScript('OnUpdate', function()
Nenue@5 662 if block:GetBottom() and not InCombatLockdown() then
Nenue@5 663 print(' '..block:GetName()..' |cFF00FF00probe hit!')
Nenue@6 664 mod.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope
Nenue@5 665 block:SetScript('OnUpdate', nil)
Nenue@5 666 end
Nenue@5 667 end)
Nenue@6 668 previousItem = itemButton
Nenue@1 669 else
Nenue@5 670 print('hidden block or unwatched quest')
Nenue@6 671 itemButton.previousItem = nil
Nenue@5 672 itemButton:Hide()
Nenue@1 673 end
Nenue@5 674 else
Nenue@5 675 print(' |cFFFF0088missing block data', itemButton:GetName())
Nenue@6 676 itemButton.previousItem = nil
Nenue@6 677 itemButton:Hide()
Nenue@1 678 end
Nenue@1 679 end
Nenue@1 680 end
Nenue@1 681
Nenue@6 682 mod.UpdateBlockAction = function (block, itemButton)
Nenue@5 683 print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()')
Nenue@5 684 if itemButton.questID ~= block.info.questID then
Nenue@5 685 print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID)
Nenue@6 686 -- something happened between this and last frame, go back and set new probes
Nenue@5 687 return mod.UpdateActionButtons()
Nenue@2 688 end
Nenue@2 689
Nenue@6 690 local previousItem = itemButton.previousItem
Nenue@6 691 local upper_bound = Scroller:GetTop() + Scroller.snap_upper
Nenue@6 692 local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize
Nenue@6 693 local point, anchor, relative
Nenue@6 694
Nenue@6 695 if block:GetBottom() < lower_bound then
Nenue@6 696 print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5))
Nenue@1 697 if previousItem then
Nenue@6 698 print('adjusting', previousItem:GetName())
Nenue@1 699 previousItem:ClearAllPoints()
Nenue@6 700 previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing)
Nenue@1 701 end
Nenue@1 702 itemButton:ClearAllPoints()
Nenue@6 703 itemButton.x = Wrapper:GetLeft() -4
Nenue@6 704 itemButton.y = Wrapper:GetBottom()
Nenue@6 705 point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT'
Nenue@6 706 Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing
Nenue@6 707
Nenue@6 708 elseif block:GetTop() > upper_bound then
Nenue@6 709 print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5))
Nenue@6 710 itemButton:ClearAllPoints()
Nenue@6 711 if previousItem then
Nenue@6 712 print('latch onto another piece')
Nenue@6 713 point, anchor, relative ='TOP', previousItem, 'BOTTOM'
Nenue@6 714 itemButton.x = 0
Nenue@6 715 itemButton.y = -itemButtonSpacing
Nenue@6 716 else
Nenue@6 717 print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop())
Nenue@6 718 point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT'
Nenue@6 719 itemButton.x = Scroller:GetLeft() -4
Nenue@6 720 itemButton.y = Scroller:GetTop()
Nenue@6 721 end
Nenue@1 722 itemButton:Show()
Nenue@6 723 Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing)
Nenue@1 724 else
Nenue@6 725 print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5))
Nenue@1 726 itemButton:ClearAllPoints()
Nenue@6 727 itemButton.x = block:GetLeft() - itemButtonSpacing
Nenue@6 728 itemButton.y = block:GetTop()
Nenue@6 729 point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT'
Nenue@1 730 end
Nenue@6 731
Nenue@6 732 itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y)
Nenue@6 733 itemButton:Show()
Nenue@1 734 end
Nenue@1 735
Nenue@1 736 mod.UpdateItemButtonCooldown = function(button)
Nenue@1 737
Nenue@1 738 end