Mercurial > wow > buffalo2
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 |