comparison Turok/Modules/Utilities/Toast.lua @ 6:a9b8b0866ece

clear out log jam
author Nenue
date Sun, 21 Feb 2016 08:32:53 -0500
parents
children 0b1a2f3dbfc4
comparison
equal deleted inserted replaced
5:8a9a6637f082 6:a9b8b0866ece
1 --- ${PACKAGE_NAME}
2 -- @file-author@
3 -- @project-revision@ @project-hash@
4 -- @file-revision@ @file-hash@
5 -- Created: 2/2/2016 12:09 AM
6
7 local mod = Turok:NewModule("Toast", "AceTimer-3.0")
8 local _G = _G
9 local db
10 local T, tostring, type, max, tinsert, UIParent, loadstring = _G.Turok, tostring, type, max, table.insert, _G.UIParent, loadstring
11 --@debug@
12 local DEBUG = true
13 --@end-debug@
14 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool
15 local print = function(...)
16 if not DEBUG then return end
17 if _G.Devian and _G.DevianDB.workspace ~= 1 then
18 _G.print('Toast', ...)
19 end
20 end
21
22 -- GLOBALS:BossBanner_OnEvent, BossBanner
23 -- kill off the default BossBanner
24 local old_bb = BossBanner_OnEvent
25 BossBanner_OnEvent = function(self, event, ...)
26 T:Print(event, ...)
27 end
28
29 T.defaults.toast = {
30 alert_hold = 2,
31 alert_fade = 1,
32 alert_flash = .6,
33 anchor = 'TOP',
34 parent = 'UIParent',
35 anchorTo = 'TOP',
36 x = 0, y= -56,
37 loot = {
38 background_color = {},
39 }
40 }
41
42 mod.events = {
43 "ACHIEVEMENT_EARNED",
44 "CRITERIA_EARNED",
45 "LFG_COMPLETION_REWARD",
46 "GUILD_CHALLENGE_COMPLETED",
47 "CHALLENGE_MODE_COMPLETED",
48 "LOOT_ITEM_ROLL_WON",
49 "SHOW_LOOT_TOAST",
50 "SHOW_LOOT_TOAST_UPGRADE",
51 "SHOW_PVP_FACTION_LOOT_TOAST",
52 "PET_BATTLE_CLOSE",
53 "STORE_PRODUCT_DELIVERED",
54 "GARRISON_BUILDING_ACTIVATABLE",
55 "GARRISON_MISSION_FINISHED",
56 "GARRISON_FOLLOWER_ADDED",
57 "GARRISON_RANDOM_MISSION_ADDED",
58 "BOSS_KILL",
59 "ENCOUNTER_LOOT_RECEIVED",
60 }
61
62 mod.events_args = {
63 ['ACHIEVEMENT_EARNED'] = {12, false},
64 ['ACHIEVEMENT_EARNED'] = {12, true},
65 ['LFG_COMPLETED_REWARD'] = {},
66 }
67 local y_factor = -1
68 local x_factor = 0
69 local tkAlerts = TkAlertContainer
70 local AlertFrame_FixPosition = function(alertFrame)
71 print(' pos:', alertFrame.order, cKey(alertFrame.x), cWord(alertFrame.y))
72 alertFrame:SetPoint('TOPLEFT', tkAlerts, 'TOPLEFT', alertFrame.x, alertFrame.y)
73 end
74
75 --- Goes through the alert container index and fixes the frame positions
76 -- used before and after an alert frame changes visibility
77 local AlertContainer_Update = function(self)
78 local anum = 1
79 local offset = 0
80 for i, alert in ipairs(tkAlerts.alerts) do
81 if alert:IsShown() then
82 alert.x = offset * x_factor
83 alert.y = offset * y_factor
84 alert.drawHeight = alert.ename:GetStringHeight()+ alert.desc:GetStringHeight()
85 alert.order = anum
86 anum = anum + 1
87 offset = offset + alert.drawHeight
88 print(' draw height:', i, cText(alert.drawHeight))
89 print(' position:', i, cPink(offset))
90 AlertFrame_FixPosition(alert)
91 print('index', i, 'shifted from position', cNum(alert.order), 'to', cNum(anum), ' at draw point', alert.y)
92 print(' draw distance update ', cNum(0), 'x', cNum(offset))
93 else
94 print('index', i, 'is not visible')
95 end
96 end
97 self:SetHeight(offset)
98 end
99
100 --- config mode blocking command
101 local AlertFrame_Block = function(alertFrame)
102 -- only do stuff when configMode is on
103 if not mod.configMode then
104 return
105 end
106 end
107
108 --- if not config mode, then fire at the end of fadeIn animation to queue fadeOut
109 local AlertFrame_Pin = function(alertFrame)
110 if not mod.configMode then
111 alertFrame.fadeOut.a1:SetStartDelay(db.alert_hold)
112 alertFrame.fadeOut:Play()
113 end
114 end
115
116 --- if not config mode, then fire at the end of fadeOut to remove the frame from view and trigger positions update
117 local AlertFrame_Remove = function(alertFrame)
118 mod.num_events = mod.num_events - 1
119 alertFrame:Hide()
120 print(mod.num_events)
121 AlertContainer_Update(tkAlerts)
122 end
123
124 --- orders all visible frames to fadeOut
125 -- @param stagger forces the spacing of startDelay times for each frame
126 local AlertContainer_Clear = function(self, stagger)
127 stagger = stagger or 0.1
128 for i = #self.alerts, 1, -1 do
129 print('clear check', i)
130 local alert = self.alerts[i]
131 if alert:IsShown() and not alert.fadeOut:IsPlaying() then
132 alert.fadeOut.a1:SetStartDelay((#self.alerts-i)* stagger)
133 alert.fadeOut:Play()
134 end
135 end
136 end
137 local AlertContainer_Unlock = function()
138 end
139
140 --- Displays a new alert
141 -- @param name text naming the class of event that occurred
142 -- @param text alert subtext describing basic info about the event
143 -- @order order (optional) sets display slot of the alert
144 local function AlertContainer_ShowAlert(self, name, text, order)
145 local db = TurokData.toast
146 mod.num_events = mod.num_events + 1
147
148 local alertFrame
149 if not order then
150 local i = 1
151 while i <= #self.alerts and not alertFrame do
152 if not self.alerts[i]:IsShown() then
153 alertFrame = self.alerts[i]
154 print('re-using alert frame #', i)
155 end
156 i = i +1
157 end
158 else
159 alertFrame = self.alerts[order]
160 end
161
162 if not alertFrame then
163 alertFrame = CreateFrame('Frame', 'TkAlertPanel'..(order or #self.alerts+1), self, 'TkAlertFrame')
164 self.alerts[#self.alerts+1] = alertFrame
165 print('creating new alert frame', #self.alerts)
166
167 alertFrame.Pin = AlertFrame_Pin
168 alertFrame.Remove = AlertFrame_Remove
169 end
170
171 alertFrame.ename:SetText(name)
172 local height1 = alertFrame.ename:GetStringHeight()
173 alertFrame.desc:SetText(text)
174 local height2 = height1+ alertFrame.desc:GetStringHeight()
175 alertFrame.desc:SetPoint('TOPLEFT', alertFrame, 'TOPLEFT', 0, -height1)
176
177 alertFrame.order = order or mod.num_events
178 alertFrame:SetSize(300, height2)
179 alertFrame:Show()
180 --alertFrame.flashIn.a1:SetDuration(db.alert_flash/2)
181 --alertFrame.flashIn.a2:SetDuration(db.alert_flash/2)
182 alertFrame.flashIn:Play()
183 if not mod.configMode then
184 AlertContainer_Update(tkAlerts)
185 end
186 end
187
188
189 --- updates the completed missions index and returns info on the mission ID if passed
190 local completedMissions
191 local Garrison_UpdateCompleteMissions = function(missionID)
192 completedMissions = C_Garrison.GetCompleteMissions()
193 --- slide entries around for reference
194 for i, set in ipairs(completedMissions) do
195 if i ~= set.missionID then
196 completedMissions[set.missionID] = set
197 completedMissions[i] = nil
198 end
199 end
200
201 if missionID and completedMissions[missionID] then
202 local m = completedMissions[missionID]
203 return m.name, m.location, m.locPrefix, m.isRare, m.followers, m.rewards, m.state
204 else
205 return false
206 end
207 end
208 --- container events handler
209 local AlertContainer_OnEvent = function (self, event, ...)
210 print(event, ...)
211 tkAlerts:Show()
212 if event == 'SHOW_LOOT_TOAST' then
213 local typeIdentifier, itemLink, quantity, specID, sex, isPersonal, lootSource = ...;
214 if typeIdentifier == "currency" then
215 AlertContainer_ShowAlert(self, itemLink, 'x'..quantity)
216 elseif typeIdentifier == "item" then
217 local _, _, _, ilvl, _, _, _, _, equipSlot = GetItemInfo(itemLink)
218 AlertContainer_ShowAlert(self, itemLink, tostring(ilvl)..' '..tostring(_G[equipSlot]))
219 end
220 elseif event == 'GARRISON_MISSION_FINISHED' then
221 local missionID = ...
222 local name, location, locPrefix, isRare, followers, rewards = Garrison_UpdateCompleteMissions(missionID)
223 local mission_info = {
224 (isRare and ('|cFF44BBFF') or ('|cFFFFFF00')..name.. '|r'),
225 }
226
227 if followers then
228 for i, guid in ipairs(followers) do
229 print(C_Garrison.GetFollowerInfo(guid))
230 end
231 end
232
233 --'|T:'..icon..':0
234
235
236 AlertContainer_ShowAlert(self, 'Mission Complete')
237 elseif event == 'GARRISON_BUILDING_ACTIVATABLE' then
238 local missionID = ...
239 elseif event == 'ACHIEVEMENT_EARNED' then
240 elseif event == 'LFG_COMPLETION_REWARD' then
241 local name, typeID, subtypeID, textureFilename, moneyBase, moneyVar, experienceBase, experienceVar, numStrangers, numRewards = GetLFGCompletionReward()
242 local _, _, _, _, hasBonusStep, isBonusStepComplete = C_Scenario.GetInfo();
243
244 end
245 end
246
247 local AlertContainer_Test = function()
248 if not mod.configMode then
249 print('starting test mode')
250 tkAlerts:Show()
251 mod.configMode = true
252
253 tkAlerts.configBG:Show()
254 tkAlerts.configBG:SetTexture(0,0.5,0,0.5)
255 tkAlerts:RegisterForDrag('LeftButton')
256 tkAlerts:EnableMouse(true)
257
258 for i, frame in ipairs(tkAlerts.tools) do
259 frame:Show()
260 end
261 -- test fillers
262 local _,_, offset, range = GetSpellTabInfo(2)
263 print(offset, range)
264
265 for i, event in ipairs(mod.events) do
266 --print(i, event)
267 local _, id = GetSpellBookItemInfo(math.random(offset, offset+range), 'spell')
268 print(id)
269
270 local name = GetSpellLink(id)
271 local text = GetSpellDescription(id)
272 if not tkAlerts.alerts[i] then
273 print('creating alert frame #', i)
274 AlertContainer_ShowAlert(tkAlerts, name, text, i)
275 else
276 print('updating alert frame #', i)
277 local alert = tkAlerts.alerts[i]
278 alert:Show()
279 alert.order = i
280 alert.ename:SetText(name)
281 alert.desc:SetText(text)
282 if alert.fadeOut:IsPlaying() then
283 alert.fadeOut:Stop()
284 alert.backdrop:SetAlpha(0.5)
285 end
286
287 alert.flashIn:Play()
288 end
289 end
290 AlertContainer_Update(tkAlerts)
291 else
292 tkAlerts:EnableMouse(false)
293 tkAlerts.configBG:Hide()
294 mod.configMode = nil
295 for i, frame in ipairs(tkAlerts.tools) do
296 frame:Hide()
297 end
298 for i, alert in ipairs(tkAlerts.alerts) do
299 for j, frame in ipairs(alert.tools) do
300 frame:Hide()
301 end
302 alert.fadeOut.a1:SetStartDelay(i*0.2)
303 alert.fadeOut:Play()
304 end
305
306 end
307 end
308
309 mod.OnEnable = function()
310 db = TurokData.toast
311
312 --- find the closest frame to the center bottom and anchor to that
313
314 local cX, cY = (GetScreenWidth() / 2), (GetScreenHeight() / 2)
315 local min_skewness = cX
316 local max_centrality, center_frame
317 for n, f in ipairs({UIParent:GetChildren()}) do
318 if type(f) == 'table' and f.GetObjectType and f.GetName then
319 if f.IsForbidden and f:IsForbidden() then
320 print(n, 'is a forbidden object')
321 else
322 local name = f:GetName()
323
324 if f:IsVisible() and f:IsMouseEnabled() then
325 print(name and name or tostring(f):sub(8), 'is a frame!')
326 local x = f:GetCenter()
327 local y = f:GetTop() -- Y need center top position
328 if (x and y) and (y <= cY) then
329 x = math.abs(x - cX) -- X works in either direction
330
331 -- distance of current - distant of record / max to get ratio of 1 where direct center results in 1
332 local skewness_factor = (cX - x) / cX
333 local vertness_factor = y / cY
334 local centrality = skewness_factor * vertness_factor
335 print('result: (', floor(x), floor(y), ') = ', skewness_factor, 'skew,', vertness_factor, 'vertness.\nTotal score:', cNum(centrality))
336 if (not max_centrality) or max_centrality < centrality then
337 center_frame = f
338 max_centrality = centrality
339 print(cWord(name and name or tostring(f):sub(8)),cPink(' is the new record!'))
340 end
341
342 end
343 end
344 end
345 end
346 end
347
348 mod.num_events = 0
349 tkAlerts.alerts = {}
350 for i, event in ipairs(mod.events) do
351 tkAlerts:RegisterEvent(event)
352 end
353
354 tkAlerts.Clear = AlertContainer_Clear
355 tkAlerts.Unlock = AlertContainer_Unlock
356 tkAlerts.Close = AlertContainer_Test
357
358 tkAlerts:ClearAllPoints()
359 tkAlerts:SetPoint(db.anchor, db.parent, db.anchorTo, db.x, db.y)
360 tkAlerts.x = db.x
361 tkAlerts.y = db.y
362 tkAlerts.parent = db.parent
363 tkAlerts.anchor = db.anchor
364 tkAlerts.anchorTo = db.anchorTo
365 tkAlerts:EnableMouse(false)
366
367 tkAlerts:SetScript('OnEvent', AlertContainer_OnEvent)
368 T:RegisterChatCommand("alert", AlertContainer_Test)
369 T:RegisterChatCommand("atest", function()
370 AlertContainer_OnEvent(tkAlerts, 'GARRISON_MISSION_FINISHED', 327)
371 end)
372 end