view FilterBar.lua @ 34:0100d923d8c3

WorldPlan: - Reward filter toggle changed to clear out other reward filters. The assumption being that one is most often looking only for that particular type of quest when they go to use it. - Fixed filter bar info falling out of sync after player-triggered world map updates. - Code stuff: -- Quest pin shown-state management makes better use of OnShow OnHide handlers, SetShown is toggled and it all goes from there -- WorldQuests module re-factored outside of the top level frame script. ClassPlan: - Available missions are now recorded; the mission list can be toggled between in-progress and available by clicking the heading.
author Nenue
date Wed, 02 Nov 2016 19:04:47 -0400
parents be4db60219ca
children 21bcff08b0f4
line wrap: on
line source
-- WorldPlan
-- FilterBar.lua
-- Created: 10/27/2016 8:55 PM
-- %file-revision%
--

local print = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or nop
local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end
local wipe, ipairs, pairs = table.wipe, ipairs, pairs

local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS


local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP
local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE
local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON
local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION

local familiars = {
  [42159] = {npc = 106552, name = 'Nightwatcher Merayl'},
  [40277] = {npc = 97804, name = 'Tiffany Nelson'},
  [40298] = {npc = 99182, name = 'Sir Galveston'},
  [40282] = {npc=  99150, name = 'Grixis Tinypop'},
  [40278] = {npc = 98270, name = 'Robert Craig'},
  [48195] = {npc = 105250, name = 'Aulier'},
  [41990] = {npc = 105674, name = 'Varenne'},
  [41860] = {npc = 104970, name = 'Xorvasc'},
  [40299] = {npc = 99210, name = 'Bodhi Sunwayver'},
  [42442] = {npc = 107489, name = 'Amalia'},
  [40280] = {npc = 99077, name = 'Bredda Tenderhide'},
  [41687] = {npc = 104553, name = 'Odrogg'},
  [41944] = {npc = 105455, name = 'Trapper Jarrun'},
  [40337] = {npc = 97709, name = 'Master Tamer Flummox'},
  [40279] = {npc = 99035, name = 'Durian Strongfruit'}
}
local familiars_id = 9696

local DEFAULT_FILTER_LAYOUT = {
  PinSize = 22,
  Border = 3,
  TrackingBorder = 2,
  TagSize = 12,
  TimeleftStage = 3,
  showNumber = true,
  numberFontObject = 'WorldPlanNumberFontThin'
}
local DEFAULT_FILTER_LIST = {
  { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" },
  { filterKey= 'rewardType', cVar = 'worldQuestFilterArtifactPower', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" },
  { filterKey= 'rewardType', cVar = 'worldQuestFilterOrderResources', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\Icons\\inv_orderhall_orderresources" },
  { filterKey= 'rewardType', cVar = 'worldQuestFilterEquipment', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" },
  { filterKey= 'rewardType', cVar = 'worldQuestFilterProfessionMaterials', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 },
  { filterKey= 'rewardType', cVar = 'worldQuestFilterGold', filterValue = REWARD_CASH, label = 'Gold', texture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" },
  { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 },
  { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", },
  { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
  { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", },
}
local defaults = {}

WorldPlanSummaryMixin = {
  selectedBountyIndex = {},
  bounties = {},
  filterList = {},
  buttons = {},
}
WorldPlanFilterPinMixin = {}

function WorldPlanSummaryMixin:OnLoad()
  WorldPlan:AddHandler(self, defaults)
  for index, info in ipairs(DEFAULT_FILTER_LIST) do
    info.zone = DEFAULT_FILTER_LAYOUT
    info.continent = DEFAULT_FILTER_LAYOUT
    info.pinMask =  "Interface\\Minimap\\UI-Minimap-Background"

    WorldPlan:AddTypeInfo(self,index, info)
  end

end


function WorldPlanSummaryMixin:OnEvent(event)
  print('|cFF00FF88'..self:GetName()..':OnEvent()', event)
  self.isStale = true
end

local bountyIndex
local debug_headers = {}

function WorldPlanSummaryMixin:Setup()
  print('|cFF00FF88'..self:GetName()..':Setup()')
  self:GetFilters()
end


function WorldPlanSummaryMixin:OnUpdate()
  if self.isStale then
    wprint('|cFF00FF00pushing update')
    self:Refresh()
  end
end

function WorldPlanSummaryMixin:OnShow()
  print('|cFF00FF88'..self:GetName()..':OnShow()')
  if self.isStale then
    self:Refresh()
  end
end

function WorldPlanSummaryMixin:GetFilters()

  print('|cFF00FFFF'..self:GetName()..':GetFilters()')

  wipe(self.filterList)

  for index, info in ipairs(DEFAULT_FILTER_LIST) do
    tinsert(self.filterList, info)
  end
  self.bounties, self.numBounties = GetQuestBountyInfoForMapID(WorldPlan.currentMapID)
  self.BountyFilters = {}
  for index, data in ipairs(self.bounties) do
    local info = self.BountyFilters[index]
    if not info then
      info  = {}
      self.BountyFilters[index] = info
    end

    local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID))

    info.filterKey = 'factionID'
    info.filterValue = data.factionID
    info.label = questTitle
    info.texture = data.icon
    print('loading emissary', questTitle)

    tinsert(self.filterList, info)
    --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
  end
end

function WorldPlanSummaryMixin:Reset()
  self.pinLayout = self:GetTypeInfo(255)
  self:GetFilters()
end

function WorldPlanSummaryMixin:Refresh()
  self:Update()
end

local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64"
local filterMask = "Interface\\Minimap\\UI-Minimap-Background"

local questResults = {{}}
function WorldPlanSummaryMixin:Update()
  local blocks = self.buttons
  local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton
  local numHeaders = 0
  print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',WorldPlan.currentMapID)


  local quests = WorldPlanQuests.QuestsByZone[WorldPlan.currentMapID] or WorldPlanQuests.QuestsByID
  local foundQuests = questResults[1]
  for index, info in ipairs(self.filterList) do
    local numQuests = 0
    local resultIndex = numHeaders + 1
    questResults[resultIndex] = questResults[resultIndex] or  {}
    wipe(questResults[resultIndex])
    for questID, pin in pairs(quests) do
      if pin.used then
        if not info.filterKey then
          numQuests = numQuests + 1
        elseif pin[info.filterKey] == info.filterValue then
          numQuests = numQuests + 1
          tinsert(questResults[resultIndex], pin)
        end
      end
    end
    print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')')

    if numQuests >= 1 then
      numHeaders = numHeaders + 1
      local button = blocks[numHeaders]
      if not blocks[numHeaders] then
        button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin')

        button:SetSize(24,24)
        button.icon:ClearAllPoints()
        button.icon:SetAllPoints(button)

        button.iconBorder:SetPoint('TOPLEFT', button, 'TOPLEFT', -2, 2)
        button.iconBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT', 2, -2)
        button.iconBorder:SetMask(filterMask)
        button.iconBorder:SetTexture(filterFill)
        button.iconBorder:SetDesaturated(true)

        button.supertrackBorder:Hide()
        blocks[numHeaders] = button
      end

      button.info = info
      button.questList = questResults[resultIndex]
      button:SetID(index)
      button.spacing = ((info.filterKey ~=  relativeFrame.filterKey) and 10) or 0
      button.relativeFrame = relativeFrame
      button:Refresh((numHeaders == 1), numQuests)
      button:Show()
      relativeFrame = button
    end

  end

  self.numHeaders = numHeaders
  for i = numHeaders + 1, #blocks do
    if blocks[i] then
      blocks[i]:Hide()
    end
    if questResults[i] then
      wipe(questResults[i])
    end
  end
  self.isStale = nil
end

function WorldPlanSummaryMixin:Cleanup()
  -- hide trailing buttons
end

local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF'}
function WorldPlanFilterPinMixin:OnEnter()
  if self.questList and #self.questList >= 1 then
    GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
    GameTooltip_ClearInsertedFrames(GameTooltip)
    GameTooltip:AddLine(self.info.label)
    for index, pin in ipairs(self.questList) do
      local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
      GameTooltip:AddLine(pin.title ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b)
      GameTooltip:AddTexture(pin.itemTexture)
      local cLine = GameTooltip:NumLines() - 1
      --print(cLine, _G['GameTooltipTexture'..cLine]:GetTexture())
      if type(pin.itemTexture) == 'number' then
        --- voodoo workaround for IDs getting coerced to string
        _G['GameTooltipTexture'..cLine]:Show()
        _G['GameTooltipTexture'..cLine]:SetTexture(pin.itemTexture)
      end
      GameTooltip:Show()
    end
  end
end

function WorldPlanFilterPinMixin:OnLeave()
  if GameTooltip:IsOwned(self) then
    GameTooltip:Hide()
  end
end

function WorldPlanFilterPinMixin:Refresh(isFirst, numQuests)
  isFirst = isFirst or self.isFirst
  numQuests = numQuests or self.numQuests

  local info = self.info

  self.isFirst = isFirst
  self.numQuests = numQuests
  self.filterKey = info.filterKey
  self.filterValue = info.filterValue
  self.tagID = info.tagID

  self.icon:SetMask(filterMask)
  self.icon:SetTexture(info.texture)
  self.count:SetText(numQuests)
  self.cVar = info.cVar

  self.itemTexture = self.texture

  if isFirst then
    self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5)
  else
    self:SetPoint('TOPRIGHT', self.relativeFrame, 'BOTTOMRIGHT', 0, -(3 + (self.spacing or 0)))
  end
  print('anchor to', self.relativeFrame:GetName(), info.mask)

  local r, g, b, a = 1,1,1,1
  local desaturated = false
  if self.cVar then
    self.iconBorder:SetVertexColor(1, 1, 1, 1)
    if GetCVarBool(self.cVar) then
      self.icon:SetVertexColor(1,1,1,1)
      self:SetAlpha(1)
    else
      self.icon:SetVertexColor(.5, .5, .5, 1)
      self:SetAlpha(0.5)
    end
  else
    self:SetAlpha(1)
    if WorldPlan.UsedFilters[self.filterKey] then
      if WorldPlan.UsedFilters[self.filterKey] == self.filterValue then
        self.iconBorder:SetVertexColor(0, 1, 0)
      else
        self.iconBorder:SetVertexColor(1, 0, 0)
      end
    else
      self.iconBorder:SetVertexColor(1, 1, 1, 1)
    end
  end

  --self:UpdateSize()
end

function WorldPlanFilterPinMixin:OnLoad()
  self:RegisterForClicks('AnyUp')
  self:SetFrameStrata('HIGH')
  self:SetFrameLevel(151)
  self:SetScript('OnUpdate', nil)
end

function WorldPlanFilterPinMixin:OnUpdate ()
end


function WorldPlanFilterPinMixin:OnLeave ()
  if GameTooltip:IsOwned(self) then
    GameTooltip:Hide()
  end
end

-- shift-click: reset filter
-- click: rotate through include(1), exclude(-1), ignore(nil)
function WorldPlanFilterPinMixin:OnClick (button)

  print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, operation)
  local filterKey = self.filterKey
  local filterValue = self.filterValue


  local operation = opPrefix


  if not filterKey then
    wipe(WorldPlan.UsedFilters)
    for i, info in ipairs(DEFAULT_FILTER_LIST) do
      if info.cVar then
        SetCVar(info.cVar, 1)
      end
    end

  elseif self.cVar then
      for i, info in ipairs(DEFAULT_FILTER_LIST) do
        if info.cVar then
          if (info.cVar ~= self.cVar) and (button == 'LeftButton') then
            SetCVar(info.cVar, 0)
          else
            SetCVar(info.cVar, 1)
          end
        end
      end
  else
    local setInclude = (button == 'LeftButton')
    local flushValue
    print('')
    if WorldPlan.UsedFilters[filterKey] == filterValue then
      WorldPlan.UsedFilters[filterKey] = nil
    else
      WorldPlan.UsedFilters[filterKey] = filterValue
    end
  end
  WorldPlan:Refresh(true)
end