diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Turok/Modules/Utilities/Toast.lua	Sun Feb 21 08:32:53 2016 -0500
@@ -0,0 +1,372 @@
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 2/2/2016 12:09 AM
+
+local mod = Turok:NewModule("Toast", "AceTimer-3.0")
+local _G = _G
+local db
+local T, tostring, type, max, tinsert, UIParent, loadstring = _G.Turok, tostring, type, max, table.insert, _G.UIParent, loadstring
+--@debug@
+local DEBUG = true
+--@end-debug@
+local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool
+local print = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Toast', ...)
+  end
+end
+
+-- GLOBALS:BossBanner_OnEvent, BossBanner
+-- kill off the default BossBanner
+local old_bb = BossBanner_OnEvent
+BossBanner_OnEvent = function(self, event, ...)
+  T:Print(event, ...)
+end
+
+T.defaults.toast = {
+  alert_hold = 2,
+  alert_fade = 1,
+  alert_flash = .6,
+  anchor = 'TOP',
+  parent = 'UIParent',
+  anchorTo = 'TOP',
+  x = 0, y= -56,
+  loot = {
+    background_color = {},
+  }
+}
+
+mod.events = {
+  "ACHIEVEMENT_EARNED",
+  "CRITERIA_EARNED",
+  "LFG_COMPLETION_REWARD",
+  "GUILD_CHALLENGE_COMPLETED",
+  "CHALLENGE_MODE_COMPLETED",
+  "LOOT_ITEM_ROLL_WON",
+  "SHOW_LOOT_TOAST",
+  "SHOW_LOOT_TOAST_UPGRADE",
+  "SHOW_PVP_FACTION_LOOT_TOAST",
+  "PET_BATTLE_CLOSE",
+  "STORE_PRODUCT_DELIVERED",
+  "GARRISON_BUILDING_ACTIVATABLE",
+  "GARRISON_MISSION_FINISHED",
+  "GARRISON_FOLLOWER_ADDED",
+  "GARRISON_RANDOM_MISSION_ADDED",
+  "BOSS_KILL",
+  "ENCOUNTER_LOOT_RECEIVED",
+}
+
+mod.events_args = {
+  ['ACHIEVEMENT_EARNED'] = {12, false},
+  ['ACHIEVEMENT_EARNED'] = {12, true},
+  ['LFG_COMPLETED_REWARD'] = {},
+}
+local y_factor = -1
+local x_factor = 0
+local tkAlerts = TkAlertContainer
+local AlertFrame_FixPosition = function(alertFrame)
+  print('   pos:', alertFrame.order, cKey(alertFrame.x), cWord(alertFrame.y))
+  alertFrame:SetPoint('TOPLEFT', tkAlerts, 'TOPLEFT', alertFrame.x, alertFrame.y)
+end
+
+--- Goes through the alert container index and fixes the frame positions
+-- used before and after an alert frame changes visibility
+local AlertContainer_Update = function(self)
+  local anum = 1
+  local offset = 0
+  for i, alert in ipairs(tkAlerts.alerts) do
+    if alert:IsShown() then
+      alert.x = offset * x_factor
+      alert.y = offset * y_factor
+      alert.drawHeight = alert.ename:GetStringHeight()+ alert.desc:GetStringHeight()
+      alert.order = anum
+      anum = anum + 1
+      offset = offset + alert.drawHeight
+      print('   draw height:', i, cText(alert.drawHeight))
+      print('      position:', i, cPink(offset))
+      AlertFrame_FixPosition(alert)
+      print('index', i, 'shifted from position', cNum(alert.order), 'to', cNum(anum), ' at draw point', alert.y)
+      print('    draw distance update ', cNum(0), 'x', cNum(offset))
+    else
+      print('index', i, 'is not visible')
+    end
+  end
+  self:SetHeight(offset)
+end
+
+--- config mode blocking command
+local AlertFrame_Block = function(alertFrame)
+  -- only do stuff when configMode is on
+  if not mod.configMode then
+    return
+  end
+end
+
+--- if not config mode, then fire at the end of fadeIn animation to queue fadeOut
+local AlertFrame_Pin = function(alertFrame)
+  if not mod.configMode then
+    alertFrame.fadeOut.a1:SetStartDelay(db.alert_hold)
+    alertFrame.fadeOut:Play()
+  end
+end
+
+--- if not config mode, then fire at the end of fadeOut to remove the frame from view and trigger positions update
+local AlertFrame_Remove = function(alertFrame)
+  mod.num_events = mod.num_events - 1
+  alertFrame:Hide()
+  print(mod.num_events)
+  AlertContainer_Update(tkAlerts)
+end
+
+--- orders all visible frames to fadeOut
+-- @param stagger forces the spacing of startDelay times for each frame
+local AlertContainer_Clear = function(self, stagger)
+  stagger = stagger or 0.1
+  for i = #self.alerts, 1, -1 do
+    print('clear check', i)
+    local alert = self.alerts[i]
+    if alert:IsShown() and not alert.fadeOut:IsPlaying() then
+      alert.fadeOut.a1:SetStartDelay((#self.alerts-i)* stagger)
+      alert.fadeOut:Play()
+    end
+  end
+end
+local AlertContainer_Unlock = function()
+end
+
+--- Displays a new alert
+-- @param name text naming the class of event that occurred
+-- @param text alert subtext describing basic info about the event
+-- @order order (optional) sets display slot of the alert
+local function AlertContainer_ShowAlert(self, name, text, order)
+  local db = TurokData.toast
+  mod.num_events = mod.num_events + 1
+
+  local alertFrame
+  if not order then
+  local i = 1
+    while i <= #self.alerts and not alertFrame do
+      if not self.alerts[i]:IsShown() then
+        alertFrame = self.alerts[i]
+        print('re-using alert frame #', i)
+      end
+      i = i +1
+    end
+  else
+    alertFrame = self.alerts[order]
+  end
+
+  if not alertFrame then
+    alertFrame = CreateFrame('Frame', 'TkAlertPanel'..(order or #self.alerts+1), self, 'TkAlertFrame')
+    self.alerts[#self.alerts+1] = alertFrame
+    print('creating new alert frame', #self.alerts)
+
+    alertFrame.Pin = AlertFrame_Pin
+    alertFrame.Remove = AlertFrame_Remove
+  end
+
+  alertFrame.ename:SetText(name)
+  local height1 = alertFrame.ename:GetStringHeight()
+  alertFrame.desc:SetText(text)
+  local height2 = height1+ alertFrame.desc:GetStringHeight()
+  alertFrame.desc:SetPoint('TOPLEFT', alertFrame, 'TOPLEFT', 0, -height1)
+
+  alertFrame.order = order or mod.num_events
+  alertFrame:SetSize(300, height2)
+  alertFrame:Show()
+  --alertFrame.flashIn.a1:SetDuration(db.alert_flash/2)
+  --alertFrame.flashIn.a2:SetDuration(db.alert_flash/2)
+  alertFrame.flashIn:Play()
+  if not mod.configMode then
+    AlertContainer_Update(tkAlerts)
+  end
+end
+
+
+--- updates the completed missions index and returns info on the mission ID if passed
+local completedMissions
+local Garrison_UpdateCompleteMissions = function(missionID)
+  completedMissions = C_Garrison.GetCompleteMissions()
+  --- slide entries around for reference
+  for i, set in ipairs(completedMissions) do
+    if i ~= set.missionID then
+      completedMissions[set.missionID] = set
+      completedMissions[i] = nil
+    end
+  end
+
+  if missionID and completedMissions[missionID] then
+    local m = completedMissions[missionID]
+    return m.name, m.location, m.locPrefix, m.isRare, m.followers, m.rewards, m.state
+  else
+    return false
+  end
+end
+--- container events handler
+local AlertContainer_OnEvent = function (self, event, ...)
+  print(event, ...)
+  tkAlerts:Show()
+  if event == 'SHOW_LOOT_TOAST' then
+    local typeIdentifier, itemLink, quantity, specID, sex, isPersonal, lootSource = ...;
+    if typeIdentifier == "currency" then
+      AlertContainer_ShowAlert(self, itemLink, 'x'..quantity)
+    elseif typeIdentifier == "item" then
+      local _, _, _, ilvl, _, _, _, _, equipSlot = GetItemInfo(itemLink)
+      AlertContainer_ShowAlert(self, itemLink, tostring(ilvl)..' '..tostring(_G[equipSlot]))
+    end
+  elseif event == 'GARRISON_MISSION_FINISHED' then
+    local missionID = ...
+    local name, location, locPrefix, isRare, followers, rewards = Garrison_UpdateCompleteMissions(missionID)
+    local mission_info = {
+      (isRare and ('|cFF44BBFF') or ('|cFFFFFF00')..name.. '|r'),
+    }
+
+    if followers then
+      for i, guid in ipairs(followers) do
+        print(C_Garrison.GetFollowerInfo(guid))
+      end
+    end
+
+      --'|T:'..icon..':0
+
+
+    AlertContainer_ShowAlert(self, 'Mission Complete')
+  elseif event == 'GARRISON_BUILDING_ACTIVATABLE' then
+    local missionID = ...
+  elseif event == 'ACHIEVEMENT_EARNED' then
+  elseif event == 'LFG_COMPLETION_REWARD' then
+    local name, typeID, subtypeID, textureFilename, moneyBase, moneyVar, experienceBase, experienceVar, numStrangers, numRewards = GetLFGCompletionReward()
+    local _, _, _, _, hasBonusStep, isBonusStepComplete = C_Scenario.GetInfo();
+
+  end
+end
+
+local AlertContainer_Test = function()
+  if not mod.configMode then
+    print('starting test mode')
+    tkAlerts:Show()
+    mod.configMode = true
+
+    tkAlerts.configBG:Show()
+    tkAlerts.configBG:SetTexture(0,0.5,0,0.5)
+    tkAlerts:RegisterForDrag('LeftButton')
+    tkAlerts:EnableMouse(true)
+
+    for i, frame in ipairs(tkAlerts.tools) do
+      frame:Show()
+    end
+    -- test fillers
+    local _,_, offset, range = GetSpellTabInfo(2)
+    print(offset, range)
+
+    for i, event in ipairs(mod.events) do
+      --print(i, event)
+      local _, id = GetSpellBookItemInfo(math.random(offset, offset+range), 'spell')
+      print(id)
+
+      local name = GetSpellLink(id)
+      local text = GetSpellDescription(id)
+      if not tkAlerts.alerts[i] then
+        print('creating alert frame #', i)
+        AlertContainer_ShowAlert(tkAlerts, name, text, i)
+      else
+        print('updating alert frame #', i)
+        local alert = tkAlerts.alerts[i]
+        alert:Show()
+        alert.order = i
+        alert.ename:SetText(name)
+        alert.desc:SetText(text)
+        if alert.fadeOut:IsPlaying() then
+          alert.fadeOut:Stop()
+          alert.backdrop:SetAlpha(0.5)
+        end
+
+        alert.flashIn:Play()
+      end
+    end
+    AlertContainer_Update(tkAlerts)
+  else
+    tkAlerts:EnableMouse(false)
+    tkAlerts.configBG:Hide()
+    mod.configMode = nil
+    for i, frame in ipairs(tkAlerts.tools) do
+      frame:Hide()
+    end
+    for i, alert in ipairs(tkAlerts.alerts) do
+      for j, frame in ipairs(alert.tools) do
+        frame:Hide()
+      end
+      alert.fadeOut.a1:SetStartDelay(i*0.2)
+      alert.fadeOut:Play()
+    end
+
+  end
+end
+
+mod.OnEnable = function()
+  db = TurokData.toast
+
+  --- find the closest frame to the center bottom and anchor to that
+
+  local cX, cY = (GetScreenWidth() / 2), (GetScreenHeight() / 2)
+  local min_skewness = cX
+  local max_centrality, center_frame
+  for n, f in ipairs({UIParent:GetChildren()}) do
+    if type(f) == 'table' and f.GetObjectType and f.GetName then
+      if f.IsForbidden and f:IsForbidden() then
+        print(n, 'is a forbidden object')
+      else
+        local name = f:GetName()
+
+        if f:IsVisible() and f:IsMouseEnabled() then
+          print(name and name or tostring(f):sub(8), 'is a frame!')
+          local x = f:GetCenter()
+          local y = f:GetTop()    -- Y need center top position
+          if (x and y) and (y <= cY) then
+            x = math.abs(x - cX) -- X works in either direction
+
+            -- distance of current - distant of record / max to get ratio of 1 where direct center results in 1
+            local skewness_factor = (cX - x) / cX
+            local vertness_factor = y / cY
+            local centrality = skewness_factor * vertness_factor
+            print('result: (', floor(x), floor(y), ') = ', skewness_factor, 'skew,', vertness_factor, 'vertness.\nTotal score:', cNum(centrality))
+            if (not max_centrality) or max_centrality < centrality then
+              center_frame = f
+              max_centrality = centrality
+              print(cWord(name and name or tostring(f):sub(8)),cPink(' is the new record!'))
+            end
+
+          end
+        end
+      end
+    end
+  end
+
+  mod.num_events = 0
+  tkAlerts.alerts = {}
+  for i, event in ipairs(mod.events) do
+    tkAlerts:RegisterEvent(event)
+  end
+
+  tkAlerts.Clear = AlertContainer_Clear
+  tkAlerts.Unlock = AlertContainer_Unlock
+  tkAlerts.Close = AlertContainer_Test
+
+  tkAlerts:ClearAllPoints()
+  tkAlerts:SetPoint(db.anchor, db.parent, db.anchorTo, db.x, db.y)
+  tkAlerts.x = db.x
+  tkAlerts.y = db.y
+  tkAlerts.parent = db.parent
+  tkAlerts.anchor = db.anchor
+  tkAlerts.anchorTo = db.anchorTo
+  tkAlerts:EnableMouse(false)
+
+  tkAlerts:SetScript('OnEvent', AlertContainer_OnEvent)
+  T:RegisterChatCommand("alert", AlertContainer_Test)
+  T:RegisterChatCommand("atest", function()
+    AlertContainer_OnEvent(tkAlerts, 'GARRISON_MISSION_FINISHED', 327)
+  end)
+end
\ No newline at end of file