view FilterBar.lua @ 100:fbd4ead2a19f v1.4.11

- More attempts to fix quest markers re-appearing when completed via the order hall spells. Hard to test due to cooldown.
author Nenue
date Thu, 18 May 2017 16:43:14 -0400
parents b29b35cb8539
children b67ba1078824
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 filtersUsed
local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64"
local filterMask = "Interface\\Minimap\\UI-Minimap-Background"

local HEADERS_SPACING = 3
local BUTTONS_SPACING = 1
local BUTTONS_HEIGHT = 20
local TOGGLE_SIZE = 20
local HEADERS_HEIGHT = 24

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 barMouseOver
local filtersDirty = true
local layoutDirty = true
local matchesDirty -- don't flag until first filter loadout

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'
}

local headerNames = {
  ['rewardType'] = 'Reward Type',
  ['worldQuestType'] = 'Quest Type',
  ['isElite'] = 'Elite',
  ['factionID'] = 'Bounties'
}

db.DefaultFilters = {
  { 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\\BattlenetWorking0", },
  { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", },
  --{ filterKey = 'isElite', filterValue = true, label = 'Elite', texture = "", desaturated = false},
  --{ filterKey = 'isElite', filterValue = false, label = 'Not-Elite', texture = "", desaturated = false},
}
local defaults = {}

WorldPlanSummaryMixin = WorldPlanSummaryMixin or {}
local Module = WorldPlanSummaryMixin
Module.selectedBountyIndex = {}
Module.bounties = {}
Module.filterList = {}
Module.Buttons = {}
Module.Headers = {}
Module.cvarFiltersDirty = false
WorldPlanFilterButtonMixin = {}
local Pin = WorldPlanFilterButtonMixin

function Module:OnLoad()
  --self:SetParent(WorldMapFrame.UIElementsFrame)
  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, arg)
  print('|cFF00FF88'..self:GetName()..':OnEvent()', event)
  if (event == 'QUEST_LOG_UPDATE') and arg then
    filtersDirty = true
    self:Refresh()
  end
end

local bountyIndex
local debug_headers = {}
local ToggleButton = {}
function Module:Setup()
  print('|cFF00FF88'..self:GetName()..':Setup()')
  self.isStale = true
  self:SetParent(WorldMapFrame.UIElementsFrame)
  --self:SetPoint('BOTTOMLEFT')
  for k,v in pairs( ToggleButton) do
    self.Toggle:SetScript(k,v)
  end
  self.Toggle:SetSize(TOGGLE_SIZE, TOGGLE_SIZE)

end


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

  barMouseOver = self:IsMouseOver()
  if barMouseOver or filtersUsed then

    self.toAlpha = 1
    self.Backdrop:Show()
  else
    self.toAlpha = 0.25
    self.Backdrop:Hide()
  end
  local cAlpha = self:GetAlpha()
  if cAlpha ~= self.toAlpha then
    if cAlpha > self.toAlpha then
      cAlpha = cAlpha - sinceLast*4
      if cAlpha <= self.toAlpha then
        cAlpha = self.toAlpha
      end
    else
      cAlpha = cAlpha + sinceLast*4
      if cAlpha >= self.toAlpha then
        cAlpha = self.toAlpha
      end
    end
  end
  self:SetAlpha(cAlpha)
end

function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
  print('|cFFFFFF00OnMapInfo()', isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
  if not isBrokenIsle then
    self:SetShown(false)
  else
    self:SetShown(true)
    if isMapOpen then
      self:Refresh()
    else
      matchesDirty = true
      layoutDirty = true
    end
  end
end

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

local IsBountyCriteria = function(poiFrame, questID)
  return IsQuestCriteriaForBounty(poiFrame.questID, questID)
end

local tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID = tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID

function Module:OnConfigUpdate()

  ToggleButton.OnShow(self.Toggle)
end

function Module:Reset()



  self:UpdateFilters('SUMMARY_RESET')
  self:UpdateMatches('SUMMARY_RESET')
  self:UpdateLayout('SUMMARY_RESET')
end

function Module:Refresh()
  self:UpdateFilters('SUMMARY_REFRESH')
  self:UpdateMatches('SUMMARY_REFRESH')
  self:UpdateLayout('SUMMARY_REFRESH')
end

local questResults = {{} }
db.FilterList = {}

function Module:UpdateFilters(event)

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

  wipe(db.FilterList)

  for index, info in ipairs(db.DefaultFilters) do
    info.used = true
    tinsert(db.FilterList, info)
  end
  self.bounties = db.Bounties
  self.BountyFilters = {}
  local numBounties = 0
  for index, data in ipairs(self.bounties) do
    if not IsQuestComplete(data.questID) then
      numBounties = numBounties + 1
      local info = self.BountyFilters[index]
      if not info then
        info  = {}
        self.BountyFilters[index] = info
        layoutDirty = true
      else
        if info.questID ~= data.questID then
          layoutDirty = true
        end
      end

      local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID))
      info.used = true
      info.filterKey = 'factionID'
      info.filterFunc = IsBountyCriteria
      info.filterValue = data.questID
      info.label = questTitle
      info.texture = data.icon
      print('loading emissary', questTitle)

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

  for i = numBounties + 1, #self.BountyFilters do
    self.BountyFilters[i].used = nil
  end

end

function Module:UpdateMatches(event)
  print('|cFF00FF00UpdateMatches()', event)
  local quests = db.QuestsByID
  local questsForMap = db.QuestsByZone[db.currentMapID] or quests

  for index, info in ipairs(db.FilterList) do
    info.GlobalMatches = info.GlobalMatches or {}
    info.LocalMatches = info.LocalMatches or {}
    wipe(info.GlobalMatches)
    wipe(info.LocalMatches)
    print(info.filterKey, info.filterValue, info.filterFunc and 'func test' or 'compare')
    for questID, pin in pairs(quests) do
      print('', questID, pin.dataLoaded, (not IsQuestComplete(questID)))
      if pin.dataLoaded and (not IsQuestComplete(questID)) then
        local keyName, keyValue = info.filterKey, info.filterValue
        local isMatch
        if info.filterFunc then
          isMatch = info.filterFunc(pin, keyValue)
          print('  running special function, result =', isMatch)
        elseif pin[keyName] and (pin[keyName] == keyValue) then
          isMatch = true
          print('  rote match')
        end
        if isMatch then
          tinsert(info.GlobalMatches, pin)
          if questsForMap[questID] then
            print('  local map')
            tinsert(info.LocalMatches, pin)
          end
        end
      end
    end
    print('global', #info.GlobalMatches, 'local', #info.LocalMatches)
  end
end

function Module:UpdateLayout(event)
  print('|cFF00FF88UpdateLayout()|r', event, 'currentMap=',db.currentMapID)

  self.filtersSelected = nil

  local currentHeader
  local relativeFrame = self
  local lastKey

  local numHeaders = 0
  local numButtons = 0

  local layoutWidth = TOGGLE_SIZE + HEADERS_SPACING * 2
  local headerWidth = HEADERS_SPACING


  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 n = 0
  for _ in pairs(mapQuests) do
    n = n + 1
  end
  print(n, 'pins to work with')


  filtersUsed = nil
  local firstCvar, lastCvar
  local isFirst = true
  for index, info in ipairs(db.FilterList) do
    --print('num here', numQuestsHere, numQuestsTotal)


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

    if #info.GlobalMatches >= 1 then
      if info.filterKey ~= lastKey then

        numHeaders = numHeaders + 1
        local nextHeader = self.Headers[numHeaders] or CreateFrame('Frame', 'FilterHeader' .. numHeaders, self,  'WorldPlanFilterHeader')
        if currentHeader then
          nextHeader:SetPoint('TOPLEFT', currentHeader, 'TOPRIGHT', 0, 0)

          currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT)
          layoutWidth = layoutWidth + headerWidth
          headerWidth = HEADERS_SPACING
        else
          nextHeader:SetPoint('TOPLEFT', TOGGLE_SIZE + HEADERS_SPACING * 2, 0)

        end

        print('  begin header '..numHeaders, 'layout width =', floor(layoutWidth+.5))
        isFirst = true
        currentHeader = nextHeader
        currentHeader.Backdrop:SetHeight(BUTTONS_HEIGHT *2)
        currentHeader.Label:SetText(headerNames[info.filterKey])
        relativeFrame = currentHeader
      end

      numButtons = numButtons + 1
      local button = self.Buttons[numButtons]
      if not button then
        button = CreateFrame('Button', 'FilterButton'..numButtons, self, 'WorldPlanFilterButton')
        button:SetSize(32,BUTTONS_HEIGHT)
        button.icon:SetTexCoord(0.1,.9,.1,(1 * (BUTTONS_HEIGHT/32)))

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

      button.info = info
      button.numQuestsTotal = #info.GlobalMatches
      button.numQuestsHere = #info.LocalMatches
      button.GlobalMatches = info.GlobalMatches
      button.LocalMatches = info.LocalMatches
      button.isFirst = isFirst
      button:SetID(index)
      button:SetParent(currentHeader)
      button.relativeFrame = relativeFrame
      button:Refresh()
      button:Show()
      relativeFrame = button
      headerWidth = headerWidth + button:GetWidth() + BUTTONS_SPACING

      isFirst = false
      if info.cVar then
        firstCvar = firstCvar or button
        lastCvar = button
      end
        lastKey = info.filterKey
    end
  end

  self.numHeaders = numHeaders
  for i = numButtons + 1, #self.Buttons do
    if self.Buttons[i] then
      self.Buttons[i]:Hide()
      wipe(self.Buttons[i].LocalMatches)
      wipe(self.Buttons[i].GlobalMatches)
    end
  end
  for i = numHeaders + 1, #self.Headers do
    if self.Headers[i] then
      self.Headers[i]:Hide()
    end
  end


  if currentHeader then
    currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT)
    layoutWidth = layoutWidth + headerWidth + HEADERS_SPACING
  end

  self:SetSize(layoutWidth, BUTTONS_HEIGHT + (BUTTONS_SPACING * 2))
  self:ClearAllPoints()
  self:SetPoint('BOTTOM')
  self.isStale = nil
  layoutDirty = nil
end

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

local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF' }
local found = {}
function Pin:OnEnter()
  if #self.GlobalMatches >= 1 then
    GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
    GameTooltip:AddLine(self.info.label)
    wipe(found)

    if self.numQuestsHere >= 1 then
      if self.numQuestsHere < self.numQuestsTotal then
        GameTooltip:AddLine('This Zone', 1, 1, 0)
      end
      for index, pin in ipairs(self.LocalMatches) do
        local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
        found[pin] = pin
        GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 0, 1, 0)
      end
    end

    if self.numQuestsHere < self.numQuestsTotal then
      if self.numQuestsHere >= 1 then
        GameTooltip:AddLine(' ')
      end
      GameTooltip:AddLine('Other Maps', 1, 1, 0)
      for index, pin in ipairs(self.GlobalMatches) do
        if not found[pin] then
          local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
          found[pin] = pin
          GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 1, 1, 1)
        end
      end
    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)

  if (self.numQuestsHere == 0) and (self.numQuestsTotal >= 1) then
    self.count:SetText('*'..self.numQuestsTotal)
    self.count:SetTextColor(0,1,1)
  elseif self.numQuestsHere < self.numQuestsTotal then
    self.count:SetText(self.numQuestsHere..'+')
    self.count:SetTextColor(1,1,0)
  else
    self.count:SetText(self.numQuestsHere)
    self.count:SetTextColor(1,1,1)
  end

  self.cVar = info.cVar
  self.itemTexture = self.texture

  self:ClearAllPoints()
  if self.isFirst then
    self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', HEADERS_SPACING, -HEADERS_SPACING)
  else
    self:SetPoint('LEFT', self.relativeFrame, 'RIGHT', BUTTONS_SPACING, 0)
  end
  --print('anchor', self.relativeFrame:IsShown(), self:GetPoint(1))

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

  local r, g, b, a = 0,0,0,1
  local desaturated = false
  if (self.numQuestsHere > 0) or db.UsedFilters[self.filterKey] 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
        filtersUsed = 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
        filtersUsed = true
        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.questList = {}
  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
end

function Pin:OnUpdate ()
  local group = self:GetParent()
  if group:IsMouseOver() and barMouseOver then
    group.Backdrop:Show()
    group.Label:Show()
  else
    group.Backdrop:Hide()
    group.Label:Hide()
  end
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(db.FilterList) do
        if info.cVar and (#info.GlobalMatches >= 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
function ToggleButton:OnEnter()

  GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
  GameTooltip:AddLine('Toggle Pins')
  GameTooltip:Show()
end
function ToggleButton:OnLeave()

  if GameTooltip:IsOwned(self) then
    GameTooltip:Hide()
  end
end
function ToggleButton:OnShow()
  self:SetChecked(db.Config.EnablePins and true or false)
end
function ToggleButton:OnHide()
  if GameTooltip:IsOwned(self) then
    GameTooltip:Hide()
  end

end
function ToggleButton:OnClick()
  --print(self:GetChecked())
  db.Config.EnablePins = self:GetChecked()
  _G.WorldPlan:OnConfigUpdate()
end