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