view ObjectiveCore.lua @ 14:ed642234f017

ObjectiveFrame - implement proper tracker name text - expanded tracker prototypes to cover "objective lines" formatting and accommodation of widget variables - implement the progress bars for bonus objectives ObjectiveStyle - moved `UpdateWrapperStyle` over and renamed it to fit semantics - change the formula for block.`height` to measure non-widget content only - allows widgets to position relative to text - size FontString `status` to match block.`height` - full block height is acquired by adding block.`height` and block.`attachmentHeight` which is calculated during objective parsing ObjectiveWidgets - use string keys for generated widgets to deal with multiple objectives under the same questID, and maybe dungeon objectives - wrapper buttons use a common code path - specialized handlers for wheel scrolling moved over to fit semantics
author Nenue
date Mon, 04 Apr 2016 03:16:22 -0400
parents 9455693fc290
children 880828018bf4
line wrap: on
line source
--- ${PACKAGE_NAME}
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 3/26/2016 1:51 AM
local B = select(2,...).frame
local pairs, setmetatable, type, tostring = pairs, setmetatable, type, tostring
local format = string.format
local M = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
local print = B.print('Objectives')
local ObjectiveTrackerFrame = ObjectiveTrackerFrame

--[[
  Full quest info is available if:
    - It's in the player quest log, or is available from the Gossip interface
    - It's being shared from another player and is acceptible
    - It's an auto-quest that is available in the current location
  Partial quest info is availabe if:
    - It's already completed (i.e. it appears in CompletedQuestInfo()).
    - It's an scheduled interval quest (daily, weekly, etc.)
    - It's contained in a quest link received from chat
  Under any other circumstances, only minimal info can be pulled:
    - Its availability to the player
    - Its relation with the currently engaged NPC
    - Its binary completion status

]]
--- Global Frames
local Wrapper = _G.VeneerObjectiveWrapper
local Scroller = Wrapper.scrollArea
local Scroll = _G.VeneerObjectiveScroll

--- Baseline defaults
M.defaults = {

}

--- list used to make things happen
M.orderedNames = {'Bonus', 'AutoQuest', 'Quest', 'Cheevs'}

--- ipairs() list of handlers for wrapper update
M.orderedHandlers = {}
M.orderedTrackers = {}
M.indexedTrackers = {}
--- pairs() list of handler frames for tracker updates
M.namedTrackers = {}

--- Handler stubs
M.AutoQuest = {
  name = "AutoQuest",
  displayName = "Local Quests",
}
M.Quest = {
  name = "Quest",
  displayName = "Quests",
}
M.Cheevs = {
  name = "Cheevs",
  displayName = "Achievements",
}
M.Bonus = {
  name = "Bonus",
  displayName = "Bonus Objectives",
}


--- Temp values set during updates
local wrapperWidth, wrapperHeight
local scrollWidth, scrollHeight
local previousBlock
local currentBlock

local frame_guide_init = function(self)
  self.testU = self.testU or self:CreateTexture('TestU', 'OVERLAY', 'VnTestLine')
  self.testB = self.testB or self:CreateTexture('TestB', 'OVERLAY', 'VnTestLine')
  self.testL = self.testL or self:CreateTexture('TestL', 'OVERLAY', 'VnTestLine')
  self.testR = self.testR or self:CreateTexture('TestR', 'OVERLAY', 'VnTestLine')
end
local frame_guide = function(self, target)
  if not target then return end
  if target:IsDragging() then return end
  local thickness = 1
  local midX, midY = target:GetCenter()
  local width, height = target:GetWidth() * 1.5, target:GetHeight() * 1.5
  --print('frame', target:GetLeft(), target:GetTop(), target:GetRight(), target:GetBottom())
  self.testB:ClearAllPoints()
  self.testB:SetPoint('TOP', UIParent, 'BOTTOMLEFT', midX, target:GetBottom())
  self.testB:SetSize(width,thickness)

  self.testU:ClearAllPoints()
  self.testU:SetPoint('BOTTOM', UIParent, 'BOTTOMLEFT', midX, target:GetTop())
  self.testU:SetSize(width,thickness)

  self.testL:ClearAllPoints()
  self.testL:SetPoint('RIGHT', UIParent, 'BOTTOMLEFT', target:GetLeft(), midY)
  self.testL:SetSize(thickness,height)

  self.testR:ClearAllPoints()
  self.testR:SetPoint('LEFT', UIParent, 'BOTTOMLEFT', target:GetRight(), midY)
  self.testR:SetSize(thickness,height)
end

--- Handler template
local CreateHandler = function (self, name, index)
  print(self, name)
  local handler = setmetatable({}, {
    __tostring = function() return name end,
    __call = function (self) M.UpdateTracker(self) end
  })
  if type(M.orderedHandlers[index]) == 'table' then
    return M.orderedHandlers[index]
  end

  print('take up locals first')
  local preset = {}
  for k,v in pairs(M[name]) do
    preset[k] = true
    if type(v) == 'table' then
      handler[k] = {}
    else
      handler[k] = v
    end
  end

  print('resulting handler contents')
  for k, v in pairs(self) do
    if not handler[k] then
      if type(v) == 'table' then
        -- assume all tables to be local data; don't inherit or ref
        handler[k] = {}
      else
        handler[k] = M.Tracker[k]
      end
    else
      print(name, 'has its own', k)
    end
  end
  print('|cFFFF4400'..tostring(name)..'|r:')
  for k, v in pairs(handler) do
    print(string.format("%24s %8s %s", (preset[k] and '|cFFFFFFFF' or '|cFFFFFF00') .. k .. '|r', type(v), tostring(v)))
  end
  M[name] = handler
  M.orderedHandlers[index] = handler
  return true
end

M.Tracker = setmetatable({}, {
  __call = CreateHandler,
  __tostring = function() return 'DEFAULT_TRACKING_HANDLER' end
})
local Tracker = M.Tracker
Tracker.numWatched = 0   --- number of entries being handled
Tracker.numBlocks = 0    --- number of blocks created
Tracker.actualBlocks = 0 --- number of blocks in use

Tracker.freeBlocks = {}  --- block heap
Tracker.usedBlocks = {}

Tracker.Watched = {}     -- find by watchIndex
Tracker.Info = {}        -- find by data ID
Tracker.BlockInfo = {}   -- find by block ID
Tracker.LogInfo = {}     -- find by log ID (quest log mainly)
Tracker.WatchInfo = {}
Tracker.LogBlock = {}
Tracker.WatchBlock = {}



Tracker.GetBlock = function(handler, blockIndex)
  local block = handler.usedBlocks[blockIndex]
  if not handler.usedBlocks[blockIndex] then
    if #handler.freeBlocks >= 1 then
      block = handler.freeBlocks[#handler.freeBlocks]
      handler.freeBlocks[#handler.freeBlocks] = nil
    else
      block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock')
      block.SetStyle = M.SetBlockStyle
      block.Select = handler.Select
      block.Open = handler.Open
      block.Remove = handler.Remove
      block.Link = handler.Link
      block:SetScript('OnMouseUp', handler.OnMouseUp)
      block:SetScript('OnMouseDown', handler.OnMouseDown)
      block:ClearAllPoints()
    end

    handler.usedBlocks[blockIndex] = block
  end
  return handler.usedBlocks[blockIndex]
end

function M:OnInitialize()
  self.InitializeWrapper()
  self.InitializeXPTracker()
  M.SetEvents()
  ObjectiveTrackerFrame:UnregisterAllEvents()
  ObjectiveTrackerFrame:Hide()

end

--[[
QUESTLINE_UPDATE	This event is not yet documented
QUESTTASK_UPDATE	This event is not yet documented
QUEST_ACCEPTED	Fires when a new quest is added to the player's quest log (which is what happens after a player accepts a quest).
QUEST_ACCEPT_CONFIRM	Fires when certain kinds of quests (e.g. NPC escort quests) are started by another member of the player's group
QUEST_AUTOCOMPLETE	Fires when a quest is automatically completed (remote handin available)
QUEST_BOSS_EMOTE	This event is not yet documented
QUEST_CHOICE_CLOSE	This event is not yet documented
QUEST_CHOICE_UPDATE	This event is not yet documented
QUEST_COMPLETE	Fires when the player is looking at the "Complete" page for a quest, at a questgiver.
QUEST_DETAIL	Fires when details of an available quest are presented by a questgiver
QUEST_FINISHED	Fires when the player ends interaction with a questgiver or ends a stage of the questgiver dialog
QUEST_GREETING	Fires when a questgiver presents a greeting along with a list of active or available quests
QUEST_ITEM_UPDATE	Fires when information about items in a questgiver dialog is updated
QUEST_LOG_UPDATE	Fires when the game client receives updates relating to the player's quest log (this event is not just related to the quests inside it)
QUEST_POI_UPDATE	This event is not yet documented
QUEST_PROGRESS	Fires when interacting with a questgiver about an active quest
QUEST_REMOVED	This event is not yet documented
QUEST_TURNED_IN	Fired when a quest is turned in
QUEST_WATCH_LIST_CHANGED	This event is not yet documented
QUEST_WATCH_OBJECTIVES_CHANGED	This event is not yet documented
QUEST_WATCH_UPDATE	Fires when the player's status regarding a quest's objectives changes, for instance picking up a required object or killing a mob for that quest. All forms of (quest objective) progress changes will trigger this event.]

TRACKED_ACHIEVEMENT_LIST_CHANGED	This event is not yet documented
TRACKED_ACHIEVEMENT_UPDATE	Fires when the player's progress changes on an achievement marked for watching in the objectives tracker
 ]]