comparison ObjectiveFrame.lua @ 1:b0447b382f36

sorting client events from maintenance logic implemented all that action buttons entail for quest items
author Nenue
date Wed, 30 Mar 2016 16:30:49 -0400
parents
children a2396b03ce63
comparison
equal deleted inserted replaced
0:3dbcad2b387d 1:b0447b382f36
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 ipairs, max, unpack = ipairs, max, unpack
8 local CreateFrame = CreateFrame
9 local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
10 local print = B.print('Objectives')
11 --------------------------------------------------------------------
12 --- Global frame layout
13 --------------------------------------------------------------------
14
15 --- Upvalues
16 local Wrapper = _G.VeneerObjectiveWrapper
17 local Scroller = Wrapper.scrollArea
18 local Scroll = _G.VeneerObjectiveScroll
19 local orderedHandlers = mod.orderedHandlers
20 local orderedNames = mod.orderedNames
21
22 --- Temp values set during updates
23 local wrapperWidth, wrapperHeight
24 local scrollWidth, scrollHeight
25 local previousBlock
26 local currentBlock
27 --- todo: map these into config table when its sorted out
28 local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]]
29 local titleSize, textSize = 15, 15
30 local titleOutline, textOutline = "OUTLINE", "OUTLINE"
31 local titleSpacing, textSpacing = 4, 3
32 local textIndent = 5
33 local wrapperMaxWidth, wrapperMaxHeight = 280, 490 -- these are the hard bounds, actual *Height variables are changed
34 local headerFont, headerSize, headerHeight = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 18, 24
35 local headerOutline, headerColor = 'OUTLINE', {1,1,1,1}
36 local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0}
37
38 local Scroller_OnShow = function()
39 Wrapper.watchMoneyReasons = 0;
40 mod.UpdateWrapper()
41 end
42
43 local Scroller_OnHide = function()
44 local self = Wrapper
45 Wrapper:UnregisterAllEvents()
46 Wrapper:SetScript('OnEvent', nil)
47 Wrapper.Background:Hide()
48 Wrapper.BackgroundR:Hide()
49 end
50
51 local Scroller_OnMouseWheel = function(self, delta)
52 local r = Scroll:GetHeight() - Scroller:GetHeight()
53 local s = self:GetVerticalScroll() - delta * floor(r/5+.5)
54 if r == 0 then return end
55 if s >= r then
56 s = r
57 elseif s < 1 then
58 s = 0
59 end
60 self:SetVerticalScroll(s)
61 print(s, r, self:GetVerticalScroll())
62
63 mod.UpdateActionButtons()
64 end
65
66 local WrapperCloseButton_OnClick = function(self)
67 if Scroller:IsVisible() then
68 Scroller:Hide()
69 else
70 Scroller:Show()
71 end
72 end
73
74
75 mod.InitializeTrackers = function()
76 for i, name in ipairs(orderedNames) do
77 if not mod.orderedHandlers[i] then
78 if mod.Tracker(name, i) then
79 local handler = mod[name]
80
81 local tracker = CreateFrame('Frame', 'Veneer'..name..'Tracker', Scroll, 'VeneerTrackerTemplate')
82 tracker.header:SetText(handler.name)
83 tracker.header:SetHeight(headerHeight)
84 tracker.header:SetFont(headerFont, headerSize, headerOutline)
85 tracker.header:SetTextColor(unpack(headerColor))
86
87 handler.Tracker = tracker
88 mod.orderedTrackers[i] = tracker
89 mod.namedTrackers[name] = tracker
90 mod.indexedTrackers[handler] = tracker
91 print('created new tracker frames for new handler')
92 end
93 end
94 end
95
96 Scroller:SetScrollChild(Scroll)
97 Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel)
98 Scroller:SetScript('OnShow', Scroller_OnShow)
99 Scroller:SetScript('OnHide', Scroller_OnHide)
100 Wrapper.close:SetScript('OnClick', WrapperCloseButton_OnClick)
101 Wrapper:SetPoint(unpack(wrapperPosition))
102 Scroller_OnShow(Scroller)
103 end
104
105 mod.defaults = {
106 ObjectiveTrackerAnchor = {'BOTTOM', 'RIGHT'},
107 ObjectiveTrackerParent = 'DebuffButton',
108 ObjectiveTrackerSize = {250, 600},
109 ObjectiveWrapperParent = '',
110 ObjectiveTrackerStyle = {
111 Normal = {
112 Title = {
113 Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, 0}},
114 Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing,
115 },
116 Text = {
117 Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, 0}},
118 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
119 },
120 },
121 Super = {
122 Title = {
123 Gradient = { MinColor = {0, .7, .6, .8}, MaxColor = {0, .7, .6, 0.2}},
124 Font = {titleFont, titleSize, titleOutline},
125 Spacing = titleSpacing, BackgroundFullWidth = true
126 },
127 Text = {
128 Gradient = { MinColor = {0, .7, .6, 0.5}, MaxColor = {0, .7, .6, 0.1} },
129 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
130 },
131 },
132 Active = {
133 Title = {
134 Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, },
135 Font = {titleFont, titleSize, titleOutline},
136 Spacing = titleSpacing,
137 BackgroundFullWidth = true
138 },
139 Text = {
140 Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, },
141 Font = {textFont, textSize, textOutline},
142 Spacing = textSpacing,
143 BackgroundFullWidth = true
144 }
145 },
146 Complete = {
147 Title = {
148 Gradient = { MinColor = {0, 1, 0, 0.34}, MaxColor = {0, 1, 0, .17}, },
149 Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing,
150 BackgroundFullWidth = true
151 },
152 Text = {
153 Gradient = { MinColor = {0, 1, 0, .25}, MaxColor = {0, 1, 0, 0.12}, },
154 Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
155 BackgroundFullWidth = true
156 }
157 },
158 }
159 }
160
161
162 --- Argument containers
163 local a1, a2, a3, a4, b1, b2, b3, b4, f1, f2, f3, w1, w2
164 mod.SetBlockStyle = function(block, name)
165 -- var names intended to reflect argument order
166 local c = mod.defaults.ObjectiveTrackerStyle[name]
167 a1, a2, a3, a4 = unpack(c.Title.Gradient.MinColor)
168 b1, b2, b3, b4 = unpack(c.Title.Gradient.MaxColor)
169 block.titlebg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4)
170
171 a1, a2, a3, a4 = unpack(c.Text.Gradient.MinColor)
172 b1, b2, b3, b4 = unpack(c.Text.Gradient.MaxColor)
173 block.bg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4)
174
175 f1, f2, f3 = unpack(c.Title.Font)
176 block.title:SetFont(f1, f2, f3)
177
178 f1, f2 ,f3 = unpack(c.Text.Font)
179 block.objectives:SetFont(f1,f2,f3)
180
181 w1 = Wrapper:GetWidth()
182 w2 = (c.Title.BackgroundFullWidth and w1 or block.title:GetStringWidth())
183
184 local titleSpacing, titleSpacing2 = c.Title.Spacing, (c.Title.Spacing * 2)
185 local textSpacing, textSpacing2 = c.Text.Spacing, (c.Text.Spacing * 2)
186
187 if block.info.isTrivial then
188 block.title:SetTextColor(0.7, 0.7, 0.7, 1)
189 elseif block.info.isComplete then
190 block.title:SetTextColor(1,1,1,1)
191 else
192 block.title:SetTextColor(0,.7,1,1)
193 end
194 block.title:SetSpacing(titleSpacing)
195 block.objectives:SetSpacing(textSpacing)
196 block.objectives:SetWordWrap(true)
197
198 local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight()
199 local blockHeight = titleHeight + titleSpacing2 + textHeight + textSpacing2
200 local blockWidth = wrapperMaxWidth
201
202 block.titlebg:SetSize(min(w1, w2), titleHeight + titleSpacing2)
203 block.bg:SetSize(w1, textHeight + textSpacing2)
204 block:SetSize(blockWidth, blockHeight)
205
206 block.title:SetPoint('TOPLEFT', block.titlebg, 'TOPLEFT', 0, -titleSpacing)
207 block.objectives:SetPoint('TOPLEFT', block.titlebg, 'BOTTOMLEFT', textIndent, -textSpacing)
208
209 -- store
210 block.titleHeight = titleHeight
211 block.textHeight = textHeight
212 block.width = blockWidth
213 block.height = blockHeight
214
215 print('|cFF88DDFFApplyStyle(', block:GetName(), ')|r', blockWidth, 'x', blockHeight, '(textH', textHeight,', titleH', titleHeight, ')')
216 end
217
218 --- Updates the selected block frame to display the given info batch
219 -- If `previousBlock` is set, it will attempt to anchor to that
220 -- @param blockNum the ordered block to be updated, not a watchIndex value
221 -- @param info the reference returned by the GetXInfo functions
222 -- REMEMBER: t.info and questData[questID] are the same table
223 mod.UpdateTrackerBlock = function (handler, blockIndex, info)
224 print('|cFF00FFFFUpdateTrackerBlock('..blockIndex..'|r')
225 if not blockIndex or not info then
226 return
227 end
228
229 local tracker = handler.Tracker
230
231 local t = handler:GetBlock(blockIndex)
232 if previousBlock then
233 if blockIndex == 1 then
234 t:SetPoint('TOPLEFT', previousBlock, 'TOPLEFT', 0, -headerHeight)
235 else
236 t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0)
237 end
238 t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0)
239 end
240 print(t:GetName(), t:GetSize())
241 print(t:GetPoint(1))
242
243 t.info = info
244
245 if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end
246 if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end
247
248 info.blockIndex = blockIndex
249 handler.BlockInfo[blockIndex] = info
250 t.Select = handler.Select
251 t.Open = handler.Open
252 t.Remove = handler.Remove
253 t.Link = handler.Link
254 t:SetScript('OnMouseUp', handler.OnMouseUp)
255 t:SetScript('OnMouseDown', handler.OnMouseDown)
256 t.title:SetText(info.title)
257
258 if info.isComplete then
259 t.objectives:Show()
260 t.objectives:SetText(info.completionText)
261 elseif info.numObjectives >= 1 then
262 t.objectives:Show()
263 print('objective lines:', info.numObjectives, 'can wrap:', t.objectives:CanWordWrap())
264 local text = ''
265 for o, obj in ipairs(t.info.objectives) do
266 local line = obj.text
267 if obj.type == 'monster' then
268 line = '|cFFFFFF00' .. line .. '|r'
269 elseif obj.type == 'item' then
270 line = '|cFF44BBFF' .. line .. '|r'
271 elseif obj.type == 'object' then
272 line = '|cFFFFFFFF' .. line .. '|r'
273 end
274 text = text .. ((text == '') and "" or "\n") .. line
275 end
276 t.objectives:SetText(text)
277
278
279 -- todo: set up a SecureActionButton template
280 if info.specialItem then
281 print('|cFF00FFFFretrieve item button')
282 mod.SetItemButton(t, info)
283 elseif t.itemButton then
284 print('|cFF00FF88drop item button')
285 mod.FreeItemButton(t, info)
286 end
287
288
289 elseif info.description then
290 t.objectives:SetText(info.description)
291 t.objectives:SetWordWrap(true)
292 else
293 t.objectives:SetText(nil)
294 end
295 local style = 'Normal'
296 if info.isComplete then
297 style = 'Complete'
298 elseif info.superTracked then
299 style = 'Super'
300 end
301
302 t:SetStyle(style)
303
304
305 local fullheight = t:GetHeight()
306 t:Show()
307 print('|cFF00FFFF)|r -> ', t, t:GetHeight(), fullheight)
308 return t
309 end
310
311 mod.UpdateTracker = function(handler)
312 print('|cFF00FF88UpdateTracker(|r|cFFFF4400' .. type(handler) .. '|r :: |cFF88FFFF' .. tostring(handler) .. '|r')
313 local tracker = handler.Tracker
314 local blockIndex = 0
315 local trackerHeight = headerHeight
316 local w = 300
317
318 previousBlock = handler.Tracker
319 local numWatched = handler.GetNumWatched()
320 local numBlocks = handler.numBlocks
321 local actualBlocks = handler.actualBlocks
322 for watchIndex = 1, 25 do
323 blockIndex = blockIndex + 1
324 if watchIndex <= numWatched then
325 local info = handler:GetInfo(watchIndex)
326 if info then
327 local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info)
328 previousBlock = currentBlock
329 print('adding ', currentBlock.height)
330 trackerHeight = trackerHeight + currentBlock.height
331 numBlocks = max(numBlocks, watchIndex)
332 actualBlocks = actualBlocks + 1
333 else
334 print('|cFFFF0000Failed to draw info for index #'..watchIndex)
335 end
336
337 elseif watchIndex <= numBlocks then
338 local used = handler.usedBlocks
339 local free = handler.freeBlocks
340 print('clean up dead quest block')
341 if used[blockIndex] then
342 used[blockIndex]:Hide()
343 used[blockIndex]:ClearAllPoints()
344 free[#free+1]= used[blockIndex]
345 used[blockIndex] = nil
346 end
347 else
348 print('Stopping scan at', blockIndex)
349 break -- done with quest stuff
350 end
351 end
352 handler.numWatched = numWatched
353 handler.numBlocks = numBlocks
354 handler.actualBlocks = actualBlocks
355 handler:Report()
356 previousBlock = nil
357 if numBlocks > 0 then
358 tracker.height = trackerHeight
359 else
360 tracker.height = 0
361 end
362
363 print('|cFF00FF88)|r ->', numBlocks, 'blocks; height', tracker.height, 'last block: ')
364 end
365
366 mod.Quest.numButtons = 0
367 local usedButtons = mod.Quest.itemButtons
368 local freeButtons = mod.Quest.freeButtons
369 mod.UpdateWrapper = function()
370 wrapperWidth = wrapperMaxWidth
371 scrollWidth = wrapperWidth
372 local wrapperBlocks = 0
373 -- Update scroll child vertical size
374 scrollHeight = 0
375 for i, handler in ipairs(orderedHandlers) do
376 mod.UpdateTracker(handler)
377 if handler.actualBlocks >= 1 then
378 local tracker = handler.Tracker
379 print('setting', handler.Tracker, 'to anchor to offset', -scrollHeight)
380 tracker:SetParent(Scroll) -- this doesn't do anything that relativeTo doesn't
381 tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight)
382 tracker:SetSize(wrapperWidth, tracker.height)
383 print('adding ', tracker.height)
384 scrollHeight = scrollHeight + tracker.height
385 end
386 wrapperBlocks = wrapperBlocks + handler.actualBlocks
387 end
388 print('final scrollHeight:', scrollHeight)
389
390
391
392 -- Update frame dimensions
393 if scrollHeight > wrapperMaxHeight then
394 print(' is larger than', wrapperMaxHeight)
395 --ScrollBar:Show()
396 --scrollWidth = wrapperMaxWidth - scrollBarWidth
397 wrapperHeight = wrapperMaxHeight
398 -- Make ThumbTexture reflect the viewing scale (smaller for longer scroll, bigger for shorter)
399 --ScrollBar:GetThumbTexture():SetHeight((wrapperMaxHeight/scrollHeight) * (wrapperMaxHeight))
400 --ScrollBar:SetWidth(scrollBarWidth)
401 --ScrollBar:SetPoint('TOPRIGHT', Scroller, 'TOPRIGHT', 0, 0)
402 --ScrollBar:SetPoint('BOTTOMLEFT', Scroller, 'BOTTOMRIGHT', -scrollBarWidth, 0)
403 --ScrollBar:SetMinMaxValues(1, scrollHeight - wrapperMaxHeight)
404 else
405 --ScrollBar:Hide()
406 wrapperHeight = scrollHeight
407 end
408 scrollWidth = floor(scrollWidth+.5)
409 scrollHeight = floor(scrollHeight+.5)
410 wrapperWidth = floor(wrapperWidth+.5)
411 wrapperHeight = floor(wrapperHeight+.5)
412 headerHeight = floor(headerHeight+.5)
413
414 if wrapperBlocks >= 1 then
415 Wrapper.Background:Show()
416 Wrapper.BackgroundR:Show()
417 else
418 Wrapper.Background:Hide()
419 Wrapper.BackgroundR:Hide()
420 return
421 end
422 --wrapperHeight = scrollHeight
423
424 print('|cFFFFFF00params:|r scroller:', scrollWidth, 'x', scrollHeight)
425 print('|cFFFFFF00params:|r scroll:', scrollWidth, 'x', scrollHeight)
426 print('|cFFFFFF00params:|r wrapper:', wrapperWidth, 'x', wrapperHeight)
427 print('|cFFFFFF00params:|r header:', headerHeight)
428
429 Scroller:SetSize(wrapperWidth, wrapperHeight)
430 Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, -headerHeight)
431 Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT')
432
433 Scroll:SetSize(scrollWidth, scrollHeight)
434 Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, 0)
435 Scroll:SetPoint('RIGHT', Scroller, 'RIGHT')
436
437 --Scroller:UpdateScrollChildRect()
438 Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight)
439
440 -- update action buttons
441
442
443 print('scroll size:', Scroll:GetSize())
444 print('scroller size:',Scroller:GetSize())
445 print('wrapper size:', Wrapper:GetSize())
446 print('scroll range :', floor(Scroller:GetVerticalScrollRange()+.5))
447
448
449 mod.UpdateActionButtons()
450 end
451
452 --- Queue any active item buttons for update for that frame
453 mod.UpdateActionButtons = function()
454 local previousItem
455 for questIndex, itemButton in pairs(usedButtons) do
456 print('|cFF00FFFF', questIndex, itemButton:GetName())
457 local block = mod.Quest.LogBlock[questIndex]
458 print(block:GetTop())
459 if block then
460 if IsQuestWatched(questIndex) then
461 -- Dispatch the probe
462 block:SetScript('OnUpdate', function()
463 print('|cFFFFFF00probing', block:GetName())
464 if block:GetBottom() then
465 print('|cFF00FF00ding ding ding!')
466 mod.UpdateBlockAction(block, itemButton, previousItem)
467 block:SetScript('OnUpdate', nil)
468 end
469 end)
470 return
471 else
472 mod.FreeItemButton(block, itemButton)
473 end
474 end
475 end
476 end
477
478 mod.UpdateBlockAction = function (block, itemButton, previousItem)
479 if block:GetBottom() < Scroller:GetBottom() then
480 print('|cFFFFFF00bottom not fully visible')
481 if previousItem then
482 previousItem:ClearAllPoints()
483 previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, 4)
484 end
485 itemButton:ClearAllPoints()
486 itemButton:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', Wrapper:GetLeft(), Wrapper:GetBottom())
487 itemButton:Show()
488 else
489 print('|cFF00FF00visible positions')
490 itemButton:ClearAllPoints()
491 itemButton:SetPoint('TOPRIGHT', UIParent, 'BOTTOMLEFT', block:GetLeft(), block:GetTop())
492 itemButton:Show()
493 end
494 end
495
496 mod.UpdateItemButtonCooldown = function(button)
497
498 end