annotate 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
rev   line source
Nenue@30 1 -- WorldPlan
Nenue@30 2 -- FilterBar.lua
Nenue@30 3 -- Created: 10/27/2016 8:55 PM
Nenue@30 4 -- %file-revision%
Nenue@30 5 --
Nenue@30 6
Nenue@30 7 local print = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or nop
Nenue@33 8 local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end
Nenue@31 9 local wipe, ipairs, pairs = table.wipe, ipairs, pairs
Nenue@30 10
Nenue@30 11 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
Nenue@30 12 local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
Nenue@30 13 local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
Nenue@30 14 local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
Nenue@30 15 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
Nenue@30 16
Nenue@30 17
Nenue@30 18 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP
Nenue@30 19 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE
Nenue@30 20 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON
Nenue@30 21 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION
Nenue@33 22
Nenue@33 23 local familiars = {
Nenue@33 24 [42159] = {npc = 106552, name = 'Nightwatcher Merayl'},
Nenue@33 25 [40277] = {npc = 97804, name = 'Tiffany Nelson'},
Nenue@33 26 [40298] = {npc = 99182, name = 'Sir Galveston'},
Nenue@33 27 [40282] = {npc= 99150, name = 'Grixis Tinypop'},
Nenue@33 28 [40278] = {npc = 98270, name = 'Robert Craig'},
Nenue@33 29 [48195] = {npc = 105250, name = 'Aulier'},
Nenue@33 30 [41990] = {npc = 105674, name = 'Varenne'},
Nenue@33 31 [41860] = {npc = 104970, name = 'Xorvasc'},
Nenue@33 32 [40299] = {npc = 99210, name = 'Bodhi Sunwayver'},
Nenue@33 33 [42442] = {npc = 107489, name = 'Amalia'},
Nenue@33 34 [40280] = {npc = 99077, name = 'Bredda Tenderhide'},
Nenue@33 35 [41687] = {npc = 104553, name = 'Odrogg'},
Nenue@33 36 [41944] = {npc = 105455, name = 'Trapper Jarrun'},
Nenue@33 37 [40337] = {npc = 97709, name = 'Master Tamer Flummox'},
Nenue@33 38 [40279] = {npc = 99035, name = 'Durian Strongfruit'}
Nenue@33 39 }
Nenue@33 40 local familiars_id = 9696
Nenue@33 41
Nenue@30 42 local DEFAULT_FILTER_LAYOUT = {
Nenue@30 43 PinSize = 22,
Nenue@30 44 Border = 3,
Nenue@30 45 TrackingBorder = 2,
Nenue@30 46 TagSize = 12,
Nenue@30 47 TimeleftStage = 3,
Nenue@30 48 showNumber = true,
Nenue@30 49 numberFontObject = 'WorldPlanNumberFontThin'
Nenue@30 50 }
Nenue@30 51 local DEFAULT_FILTER_LIST = {
Nenue@30 52 { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" },
Nenue@30 53 { filterKey= 'rewardType', cVar = 'worldQuestFilterArtifactPower', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" },
Nenue@31 54 { filterKey= 'rewardType', cVar = 'worldQuestFilterOrderResources', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\Icons\\inv_orderhall_orderresources" },
Nenue@30 55 { filterKey= 'rewardType', cVar = 'worldQuestFilterEquipment', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" },
Nenue@30 56 { filterKey= 'rewardType', cVar = 'worldQuestFilterProfessionMaterials', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 },
Nenue@30 57 { filterKey= 'rewardType', cVar = 'worldQuestFilterGold', filterValue = REWARD_CASH, label = 'Gold', texture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" },
Nenue@30 58 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 },
Nenue@30 59 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", },
Nenue@30 60 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
Nenue@30 61 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", },
Nenue@30 62 }
Nenue@30 63 local defaults = {}
Nenue@30 64
Nenue@30 65 WorldPlanSummaryMixin = {
Nenue@30 66 selectedBountyIndex = {},
Nenue@30 67 bounties = {},
Nenue@30 68 filterList = {},
Nenue@30 69 buttons = {},
Nenue@30 70 }
Nenue@30 71 WorldPlanFilterPinMixin = {}
Nenue@30 72
Nenue@30 73 function WorldPlanSummaryMixin:OnLoad()
Nenue@30 74 WorldPlan:AddHandler(self, defaults)
Nenue@30 75 for index, info in ipairs(DEFAULT_FILTER_LIST) do
Nenue@30 76 info.zone = DEFAULT_FILTER_LAYOUT
Nenue@30 77 info.continent = DEFAULT_FILTER_LAYOUT
Nenue@30 78 info.pinMask = "Interface\\Minimap\\UI-Minimap-Background"
Nenue@30 79
Nenue@30 80 WorldPlan:AddTypeInfo(self,index, info)
Nenue@30 81 end
Nenue@30 82
Nenue@30 83 end
Nenue@30 84
Nenue@30 85
Nenue@30 86 function WorldPlanSummaryMixin:OnEvent(event)
Nenue@33 87 print('|cFF00FF88'..self:GetName()..':OnEvent()', event)
Nenue@33 88 self.isStale = true
Nenue@30 89 end
Nenue@30 90
Nenue@30 91 local bountyIndex
Nenue@30 92 local debug_headers = {}
Nenue@30 93
Nenue@30 94 function WorldPlanSummaryMixin:Setup()
Nenue@33 95 print('|cFF00FF88'..self:GetName()..':Setup()')
Nenue@30 96 self:GetFilters()
Nenue@30 97 end
Nenue@30 98
Nenue@30 99
Nenue@33 100 function WorldPlanSummaryMixin:OnUpdate()
Nenue@33 101 if self.isStale then
Nenue@33 102 wprint('|cFF00FF00pushing update')
Nenue@33 103 self:Refresh()
Nenue@33 104 end
Nenue@30 105 end
Nenue@33 106
Nenue@33 107 function WorldPlanSummaryMixin:OnShow()
Nenue@33 108 print('|cFF00FF88'..self:GetName()..':OnShow()')
Nenue@32 109 if self.isStale then
Nenue@32 110 self:Refresh()
Nenue@32 111 end
Nenue@32 112 end
Nenue@30 113
Nenue@30 114 function WorldPlanSummaryMixin:GetFilters()
Nenue@30 115
Nenue@33 116 print('|cFF00FFFF'..self:GetName()..':GetFilters()')
Nenue@30 117
Nenue@30 118 wipe(self.filterList)
Nenue@30 119
Nenue@30 120 for index, info in ipairs(DEFAULT_FILTER_LIST) do
Nenue@30 121 tinsert(self.filterList, info)
Nenue@30 122 end
Nenue@30 123 self.bounties, self.numBounties = GetQuestBountyInfoForMapID(WorldPlan.currentMapID)
Nenue@30 124 self.BountyFilters = {}
Nenue@30 125 for index, data in ipairs(self.bounties) do
Nenue@30 126 local info = self.BountyFilters[index]
Nenue@30 127 if not info then
Nenue@30 128 info = {}
Nenue@30 129 self.BountyFilters[index] = info
Nenue@30 130 end
Nenue@30 131
Nenue@30 132 local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID))
Nenue@30 133
Nenue@30 134 info.filterKey = 'factionID'
Nenue@30 135 info.filterValue = data.factionID
Nenue@30 136 info.label = questTitle
Nenue@30 137 info.texture = data.icon
Nenue@30 138 print('loading emissary', questTitle)
Nenue@30 139
Nenue@30 140 tinsert(self.filterList, info)
Nenue@30 141 --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
Nenue@30 142 end
Nenue@30 143 end
Nenue@30 144
Nenue@30 145 function WorldPlanSummaryMixin:Reset()
Nenue@30 146 self.pinLayout = self:GetTypeInfo(255)
Nenue@30 147 self:GetFilters()
Nenue@30 148 end
Nenue@30 149
Nenue@33 150 function WorldPlanSummaryMixin:Refresh()
Nenue@33 151 self:Update()
Nenue@30 152 end
Nenue@30 153
Nenue@30 154 local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64"
Nenue@30 155 local filterMask = "Interface\\Minimap\\UI-Minimap-Background"
Nenue@31 156
Nenue@31 157 local questResults = {{}}
Nenue@33 158 function WorldPlanSummaryMixin:Update()
Nenue@30 159 local blocks = self.buttons
Nenue@30 160 local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton
Nenue@30 161 local numHeaders = 0
Nenue@33 162 print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',WorldPlan.currentMapID)
Nenue@30 163
Nenue@30 164
Nenue@33 165 local quests = WorldPlanQuests.QuestsByZone[WorldPlan.currentMapID] or WorldPlanQuests.QuestsByID
Nenue@31 166 local foundQuests = questResults[1]
Nenue@30 167 for index, info in ipairs(self.filterList) do
Nenue@30 168 local numQuests = 0
Nenue@31 169 local resultIndex = numHeaders + 1
Nenue@31 170 questResults[resultIndex] = questResults[resultIndex] or {}
Nenue@31 171 wipe(questResults[resultIndex])
Nenue@30 172 for questID, pin in pairs(quests) do
Nenue@30 173 if pin.used then
Nenue@30 174 if not info.filterKey then
Nenue@30 175 numQuests = numQuests + 1
Nenue@30 176 elseif pin[info.filterKey] == info.filterValue then
Nenue@30 177 numQuests = numQuests + 1
Nenue@31 178 tinsert(questResults[resultIndex], pin)
Nenue@30 179 end
Nenue@30 180 end
Nenue@30 181 end
Nenue@30 182 print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')')
Nenue@30 183
Nenue@30 184 if numQuests >= 1 then
Nenue@30 185 numHeaders = numHeaders + 1
Nenue@30 186 local button = blocks[numHeaders]
Nenue@30 187 if not blocks[numHeaders] then
Nenue@30 188 button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin')
Nenue@30 189
Nenue@30 190 button:SetSize(24,24)
Nenue@30 191 button.icon:ClearAllPoints()
Nenue@30 192 button.icon:SetAllPoints(button)
Nenue@30 193
Nenue@30 194 button.iconBorder:SetPoint('TOPLEFT', button, 'TOPLEFT', -2, 2)
Nenue@30 195 button.iconBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT', 2, -2)
Nenue@30 196 button.iconBorder:SetMask(filterMask)
Nenue@30 197 button.iconBorder:SetTexture(filterFill)
Nenue@30 198 button.iconBorder:SetDesaturated(true)
Nenue@30 199
Nenue@30 200 button.supertrackBorder:Hide()
Nenue@30 201 blocks[numHeaders] = button
Nenue@30 202 end
Nenue@30 203
Nenue@30 204 button.info = info
Nenue@31 205 button.questList = questResults[resultIndex]
Nenue@30 206 button:SetID(index)
Nenue@30 207 button.spacing = ((info.filterKey ~= relativeFrame.filterKey) and 10) or 0
Nenue@30 208 button.relativeFrame = relativeFrame
Nenue@30 209 button:Refresh((numHeaders == 1), numQuests)
Nenue@30 210 button:Show()
Nenue@30 211 relativeFrame = button
Nenue@30 212 end
Nenue@30 213
Nenue@30 214 end
Nenue@30 215
Nenue@30 216 self.numHeaders = numHeaders
Nenue@30 217 for i = numHeaders + 1, #blocks do
Nenue@30 218 if blocks[i] then
Nenue@30 219 blocks[i]:Hide()
Nenue@30 220 end
Nenue@31 221 if questResults[i] then
Nenue@31 222 wipe(questResults[i])
Nenue@31 223 end
Nenue@30 224 end
Nenue@32 225 self.isStale = nil
Nenue@30 226 end
Nenue@30 227
Nenue@30 228 function WorldPlanSummaryMixin:Cleanup()
Nenue@30 229 -- hide trailing buttons
Nenue@30 230 end
Nenue@30 231
Nenue@31 232 local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF'}
Nenue@30 233 function WorldPlanFilterPinMixin:OnEnter()
Nenue@31 234 if self.questList and #self.questList >= 1 then
Nenue@31 235 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
Nenue@31 236 GameTooltip_ClearInsertedFrames(GameTooltip)
Nenue@31 237 GameTooltip:AddLine(self.info.label)
Nenue@31 238 for index, pin in ipairs(self.questList) do
Nenue@31 239 local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
Nenue@31 240 GameTooltip:AddLine(pin.title ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b)
Nenue@31 241 GameTooltip:AddTexture(pin.itemTexture)
Nenue@31 242 local cLine = GameTooltip:NumLines() - 1
Nenue@32 243 --print(cLine, _G['GameTooltipTexture'..cLine]:GetTexture())
Nenue@31 244 if type(pin.itemTexture) == 'number' then
Nenue@31 245 --- voodoo workaround for IDs getting coerced to string
Nenue@31 246 _G['GameTooltipTexture'..cLine]:Show()
Nenue@31 247 _G['GameTooltipTexture'..cLine]:SetTexture(pin.itemTexture)
Nenue@31 248 end
Nenue@31 249 GameTooltip:Show()
Nenue@31 250 end
Nenue@31 251 end
Nenue@30 252 end
Nenue@30 253
Nenue@31 254 function WorldPlanFilterPinMixin:OnLeave()
Nenue@31 255 if GameTooltip:IsOwned(self) then
Nenue@31 256 GameTooltip:Hide()
Nenue@31 257 end
Nenue@31 258 end
Nenue@30 259
Nenue@30 260 function WorldPlanFilterPinMixin:Refresh(isFirst, numQuests)
Nenue@30 261 isFirst = isFirst or self.isFirst
Nenue@30 262 numQuests = numQuests or self.numQuests
Nenue@30 263
Nenue@30 264 local info = self.info
Nenue@30 265
Nenue@30 266 self.isFirst = isFirst
Nenue@30 267 self.numQuests = numQuests
Nenue@30 268 self.filterKey = info.filterKey
Nenue@30 269 self.filterValue = info.filterValue
Nenue@30 270 self.tagID = info.tagID
Nenue@30 271
Nenue@30 272 self.icon:SetMask(filterMask)
Nenue@30 273 self.icon:SetTexture(info.texture)
Nenue@30 274 self.count:SetText(numQuests)
Nenue@30 275 self.cVar = info.cVar
Nenue@30 276
Nenue@30 277 self.itemTexture = self.texture
Nenue@30 278
Nenue@30 279 if isFirst then
Nenue@30 280 self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5)
Nenue@30 281 else
Nenue@30 282 self:SetPoint('TOPRIGHT', self.relativeFrame, 'BOTTOMRIGHT', 0, -(3 + (self.spacing or 0)))
Nenue@30 283 end
Nenue@30 284 print('anchor to', self.relativeFrame:GetName(), info.mask)
Nenue@30 285
Nenue@30 286 local r, g, b, a = 1,1,1,1
Nenue@31 287 local desaturated = false
Nenue@31 288 if self.cVar then
Nenue@31 289 self.iconBorder:SetVertexColor(1, 1, 1, 1)
Nenue@33 290 if GetCVarBool(self.cVar) then
Nenue@31 291 self.icon:SetVertexColor(1,1,1,1)
Nenue@31 292 self:SetAlpha(1)
Nenue@31 293 else
Nenue@31 294 self.icon:SetVertexColor(.5, .5, .5, 1)
Nenue@31 295 self:SetAlpha(0.5)
Nenue@30 296 end
Nenue@30 297 else
Nenue@31 298 self:SetAlpha(1)
Nenue@31 299 if WorldPlan.UsedFilters[self.filterKey] then
Nenue@31 300 if WorldPlan.UsedFilters[self.filterKey] == self.filterValue then
Nenue@31 301 self.iconBorder:SetVertexColor(0, 1, 0)
Nenue@31 302 else
Nenue@31 303 self.iconBorder:SetVertexColor(1, 0, 0)
Nenue@31 304 end
Nenue@31 305 else
Nenue@31 306 self.iconBorder:SetVertexColor(1, 1, 1, 1)
Nenue@30 307 end
Nenue@30 308 end
Nenue@31 309
Nenue@30 310 --self:UpdateSize()
Nenue@30 311 end
Nenue@30 312
Nenue@30 313 function WorldPlanFilterPinMixin:OnLoad()
Nenue@30 314 self:RegisterForClicks('AnyUp')
Nenue@30 315 self:SetFrameStrata('HIGH')
Nenue@30 316 self:SetFrameLevel(151)
Nenue@30 317 self:SetScript('OnUpdate', nil)
Nenue@30 318 end
Nenue@30 319
Nenue@30 320 function WorldPlanFilterPinMixin:OnUpdate ()
Nenue@30 321 end
Nenue@30 322
Nenue@33 323
Nenue@30 324 function WorldPlanFilterPinMixin:OnLeave ()
Nenue@30 325 if GameTooltip:IsOwned(self) then
Nenue@30 326 GameTooltip:Hide()
Nenue@30 327 end
Nenue@30 328 end
Nenue@30 329
Nenue@30 330 -- shift-click: reset filter
Nenue@30 331 -- click: rotate through include(1), exclude(-1), ignore(nil)
Nenue@30 332 function WorldPlanFilterPinMixin:OnClick (button)
Nenue@30 333
Nenue@31 334 print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, operation)
Nenue@30 335 local filterKey = self.filterKey
Nenue@30 336 local filterValue = self.filterValue
Nenue@30 337
Nenue@30 338
Nenue@30 339 local operation = opPrefix
Nenue@30 340
Nenue@30 341
Nenue@30 342 if not filterKey then
Nenue@30 343 wipe(WorldPlan.UsedFilters)
Nenue@33 344 for i, info in ipairs(DEFAULT_FILTER_LIST) do
Nenue@33 345 if info.cVar then
Nenue@33 346 SetCVar(info.cVar, 1)
Nenue@33 347 end
Nenue@33 348 end
Nenue@33 349
Nenue@31 350 elseif self.cVar then
Nenue@33 351 for i, info in ipairs(DEFAULT_FILTER_LIST) do
Nenue@33 352 if info.cVar then
Nenue@33 353 if (info.cVar ~= self.cVar) and (button == 'LeftButton') then
Nenue@33 354 SetCVar(info.cVar, 0)
Nenue@33 355 else
Nenue@33 356 SetCVar(info.cVar, 1)
Nenue@33 357 end
Nenue@33 358 end
Nenue@33 359 end
Nenue@30 360 else
Nenue@31 361 local setInclude = (button == 'LeftButton')
Nenue@31 362 local flushValue
Nenue@31 363 print('')
Nenue@31 364 if WorldPlan.UsedFilters[filterKey] == filterValue then
Nenue@31 365 WorldPlan.UsedFilters[filterKey] = nil
Nenue@31 366 else
Nenue@31 367 WorldPlan.UsedFilters[filterKey] = filterValue
Nenue@30 368 end
Nenue@30 369 end
Nenue@33 370 WorldPlan:Refresh(true)
Nenue@30 371 end