view FilterBar.lua @ 43:77c2ffb5c7f5 v1.0-rc11

- Removed possible refresh loop occurring in non-BrokenIsle zones
author Nenue
date Sun, 25 Dec 2016 15:47:17 -0500
parents 79e5e96e5f18
children db570c6a0ffb
line wrap: on
line source
-- WorldPlan
-- FilterBar.lua
-- Created: 10/27/2016 8:55 PM
-- %file-revision%
--
local _, db = ...
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

db.DefaultFilterType = {
  iconWidth = 24,
  iconHeight = 18,
  borderWidth = 3,
  highlightWidth = 2,
  TagSize = 12,
  TimeleftStage = 3,
  showNumber = true,
  numberFontObject = 'WorldPlanNumberFontThin'
}
db.DefaultFilters = {
  { 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 = WorldPlanSummaryMixin or {}
local Module = WorldPlanSummaryMixin
Module.selectedBountyIndex = {}
Module.bounties = {}
Module.filterList = {}
Module.buttons = {}
Module.cvarFiltersDirty = false
WorldPlanFilterPinMixin = {}
local Pin = WorldPlanFilterPinMixin

function Module:OnLoad()
  self:SetParent(WorldMapFrame)
  WorldPlan:AddHandler(self)
  for index, info in ipairs(db.DefaultFilters) do
    info.zone = db.DefaultFilterType
    info.continent = db.DefaultFilterType
    info.pinMask =  "Interface\\Minimap\\UI-Minimap-Background"
    WorldPlan:AddTypeInfo(self,index, info)
  end

end


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

local bountyIndex
local debug_headers = {}

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


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

function Module:OnMapInfo(isBrokenIsle, mapAreaID)
  if not isBrokenIsle then
    self:SetShown(false)
  else
    self:SetShown(true)
    self:Refresh()
  end
end

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

local tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID = tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID
function Module:GetFilters()

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

  wipe(self.filterList)

  for index, info in ipairs(db.DefaultFilters) do
    tinsert(self.filterList, info)
  end
  self.bounties, self.numBounties = GetQuestBountyInfoForMapID(db.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 Module:Reset()
  self.pinLayout = self:GetTypeInfo(255)
  self:GetFilters()
end

function Module:Refresh()
  self:GetFilters()
  self:Update()
end

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

local questResults = {{}}
function Module:Update()
  local blocks = self.buttons

  local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton
  if FlightMapFrame and FlightMapFrame:IsVisible() then
    relativeFrame = FlightMapFrame
  end
  self:SetParent(relativeFrame)
  self:SetPoint('TOPRIGHT')

    local numHeaders = 0
  print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',WorldPlan.currentMapID)


  local layout = db.DefaultFilterType
  local borderWidth = layout.iconWidth + (layout.borderWidth * 2)
  local highlightWidth = borderWidth + (layout.highlightWidth * 2)
  local mapQuests = db.QuestsByZone[db.currentMapID] or db.QuestsByID
    local firstCvar, lastCvar
  for index, info in ipairs(self.filterList) do
    local numQuestsHere = 0
    local numQuestsTotal = 0
    info.questList = info.questList or {}
    wipe(info.questList)

    for questID, pin in pairs(db.QuestsByID) do
      print(pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION, (db.Config.ShowAllProfessionQuests or pin.isKnownProfession))
      if (pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION) or (db.Config.ShowAllProfessionQuests or pin.isKnownProfession) then
        print(pin.title)
        if not info.filterKey then
          if mapQuests[questID] then
              numQuestsHere = numQuestsHere + 1
          end
          numQuestsTotal = numQuestsTotal + 1
        elseif pin[info.filterKey] == info.filterValue then
          if mapQuests[questID] then
            numQuestsHere = numQuestsHere + 1
            tinsert(info.questList, pin)
          end
          numQuestsTotal = numQuestsTotal + 1
        end
      end
    end
    --print('num here', numQuestsHere, numQuestsTotal)
    info.totalQuests = maxQuests

    --print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')')

    if numQuestsTotal >= 1 then
      numHeaders = numHeaders + 1
      local button = blocks[numHeaders]
      if not blocks[numHeaders] then
        button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, self, 'WorldPlanFilterPin')
        button:SetSize(32,20)
        button.icon:SetTexCoord(0.1,.9,.1,(1 * (20/32)))

        button.RewardBorder:ClearAllPoints()
        button.RewardBorder:SetPoint('TOPLEFT', button, 'TOPLEFT')
        button.RewardBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT')


        blocks[numHeaders] = button
      end

      button.info = info
      button.numQuestsTotal = numQuestsTotal
      button.numQuestsHere = numQuestsHere
      button.questList = info.questList
      button.isFirst = (numHeaders == 1)
      button:SetID(index)
      button.spacing = ((relativeFrame.cVar and (not info.cVar)) or (relativeFrame.filterKey ~= info.filterKey)) and 5 or 1
      button.relativeFrame = relativeFrame
      button:Refresh()
      button:Show()
      relativeFrame = button

      if info.cVar then
        firstCvar = firstCvar or button
        lastCvar = button
      end

    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 Module:Cleanup()
  -- hide trailing buttons
end

local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF'}
function Pin:OnEnter()
  if #self.questList >= 1 then
    GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
    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('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b)
    end
    GameTooltip:AddLine(self.numQuestsTotal .. ' total')
    GameTooltip:Show()
  end
end

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

function Pin:Refresh()
  local info = self.info
  self.filterKey = info.filterKey
  self.filterValue = info.filterValue
  self.tagID = info.tagID

  self.icon:SetTexture(info.texture)
  self.count:SetText(self.numQuestsHere)
  self.cVar = info.cVar

  self.itemTexture = self.texture

  if self.isFirst then
    if FlightMapFrame and FlightMapFrame:IsVisible() then
      self:SetPoint('TOPRIGHT', FlightMapFrame, 'TOPRIGHT', -4, -25)
    else
      self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5)
    end

  else
    self:SetPoint('TOPRIGHT', self.relativeFrame, 'BOTTOMRIGHT', 0, -(self.spacing or 0))
  end
  print('anchor to', self.relativeFrame:GetName(), info.mask)

  self.icon:SetDesaturated(self.numQuestsHere == 0)

  local r, g, b, a = 0,0,0,1
  local desaturated = false
  if (self.numQuestsHere > 0) then
    if self.cVar then
      if GetCVarBool(self.cVar) then
        self.count:SetTextColor(1,1,1)
        r,g,b,a = 0, 0, 0, 1
      else
        self:GetParent().cvarFiltersDirty = true
        self.count:SetTextColor(1,0,0)
        self.icon:SetDesaturated(true)
        r,g,b,a = 1, 0, 0, 0.5
      end
    else
      if db.UsedFilters[self.filterKey] then
        if db.UsedFilters[self.filterKey] == self.filterValue then
          self.count:SetTextColor(0,1,0)
          r, g, b = 0, 1, 0
        else
          self.count:SetTextColor(1,0,0)
          r, g, b = 1, 0, 0
        end
      else

        self.count:SetTextColor(1,1,1)
        if self.filterKey == 'worldQuestType' then
          r, g, b = 0, 0, 1
        elseif self.filterKey == 'factionID' then
          r, g, b = 1, 1, 0
        end
      end
    end
  end
  self.RewardBorder:SetColorTexture(r, g, b)
  self:SetAlpha(a)

  --self:UpdateSize()
end

function Pin:OnLoad()
  self:RegisterForClicks('AnyUp')
  self:SetFrameStrata('HIGH')
  self:SetFrameLevel(151)
  self:SetScript('OnUpdate', nil)
  self.questList = {}
  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
end

function Pin:OnUpdate ()
end

-- shift-click: reset filter
-- click: rotate through include(1), exclude(-1), ignore(nil)
local filtered_report = {}
local RESET_FILTER = "|cFFFFFFFF+%s|r"
local FILTER_EXCLUDE_TYPE = '|cFFFF0000-%s|r'
local FILTER_INCLUDE_TYPE = '|cFF00FF00+%s|r'
function Pin:OnClick (button)

  local filterKey = self.filterKey
  local filterValue = self.filterValue
  local cVar = self.cVar
  local parent = self:GetParent()
  local setDirty

  print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, cVar, parent)

  local resetMode = (button == 'RightButton')
  wipe(filtered_report)
  if not (filterKey or cVar) then
    for i, info in ipairs(db.DefaultFilters) do
      if info.cVar then
        SetCVar(info.cVar, 1)
      elseif info.filterKey then
        if db.UsedFilters[info.filterKey] then
          db.UsedFilters[info.filterKey] = nil
        end
      end
    end
    parent.cvarFiltersDirty = false

    --WorldPlan:print('All filters reset.')
  elseif cVar then
    if resetMode then
      print('|cFFFF4400cleaning dirty')
      for i, info in ipairs(db.DefaultFilters) do
        if info.cVar then
          parent.cvarFiltersDirty = false
          SetCVar(info.cVar, 1)
        end
      end
      --WorldPlan:print('Reward filters reset.')
    elseif parent.cvarFiltersDirty == true then
      if GetCVarBool(cVar) then
        tinsert(filtered_report, FILTER_EXCLUDE_TYPE:format(tostring(self.info.label)))
        SetCVar(cVar, 0)
      else

        tinsert(filtered_report, FILTER_INCLUDE_TYPE:format(tostring(self.info.label)))
        SetCVar(cVar, 1)
      end

      -- check the visible filters and consider it clean if they're all lit
      parent.cvarFiltersDirty = false
      for i, info in ipairs(parent.filterList) do
        if info.cVar and (#info.questList >= 1) then
          print(info.cVar, GetCVarBool(info.cVar))
          if GetCVarBool(info.cVar) == false then
            parent.cvarFiltersDirty = true
            print('|cFFFF4400still dirty')
            break
          end
        end
      end
    else
      print('|cFFFF4400making dirty')
      for i, info in ipairs(db.DefaultFilters) do
        if info.cVar then
          local msgType = (cVar == info.cVar) and FILTER_INCLUDE_TYPE or FILTER_EXCLUDE_TYPE
          SetCVar(info.cVar, ((cVar == info.cVar) and 1) or 0)
          tinsert(filtered_report, msgType:format(info.label))
        end
      end
      parent.cvarFiltersDirty = true
    end
  else
    if resetMode then
      wipe(db.UsedFilters)
      --WorldPlan:print('Type filters reset.')
    else
      if (db.UsedFilters[filterKey] == filterValue) or resetMode then
        db.UsedFilters[filterKey] = nil
        tinsert(filtered_report,  FILTER_INCLUDE_TYPE:format(tostring(filterKey)))
      else
        db.UsedFilters[filterKey] = filterValue
        tinsert(filtered_report,  FILTER_EXCLUDE_TYPE:format(tostring(filterKey)))
      end
    end
  end
  if #filtered_report >= 1 then
    --WorldPlan:print('Setting filter(s):', table.concat(filtered_report, ', '))
  end
  WorldPlan:Refresh(true)
end