annotate FilterBar.lua @ 113:03e4a8b93012 v7.3.0-2

7.3 Updates - Added some map frame adjustments to keep the filter bar from obstructing edge of zone clicks KNOWN ISSUES: - Argus quests can only be filtered when viewing Argus maps - Main Argus map in the WorldMapFrame has misaligned pins; this is due to it using a different map texture from what is used in the teleporter map, so all the POI coordinates are based on that map in the client info
author Nenue
date Tue, 05 Sep 2017 03:14:34 -0400
parents b67ba1078824
children a4dfdd4f1cf3
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@40 6 local _, db = ...
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@93 18 local filtersUsed
Nenue@93 19 local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64"
Nenue@93 20 local filterMask = "Interface\\Minimap\\UI-Minimap-Background"
Nenue@93 21
Nenue@93 22 local HEADERS_SPACING = 3
Nenue@93 23 local BUTTONS_SPACING = 1
Nenue@93 24 local BUTTONS_HEIGHT = 20
Nenue@93 25 local TOGGLE_SIZE = 20
Nenue@95 26 local HEADERS_HEIGHT = 24
Nenue@93 27
Nenue@30 28 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP
Nenue@30 29 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE
Nenue@30 30 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON
Nenue@30 31 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION
Nenue@33 32
Nenue@93 33 local barMouseOver
Nenue@93 34 local filtersDirty = true
Nenue@93 35 local layoutDirty = true
Nenue@93 36 local matchesDirty -- don't flag until first filter loadout
Nenue@93 37
Nenue@33 38 local familiars = {
Nenue@33 39 [42159] = {npc = 106552, name = 'Nightwatcher Merayl'},
Nenue@33 40 [40277] = {npc = 97804, name = 'Tiffany Nelson'},
Nenue@33 41 [40298] = {npc = 99182, name = 'Sir Galveston'},
Nenue@33 42 [40282] = {npc= 99150, name = 'Grixis Tinypop'},
Nenue@33 43 [40278] = {npc = 98270, name = 'Robert Craig'},
Nenue@33 44 [48195] = {npc = 105250, name = 'Aulier'},
Nenue@33 45 [41990] = {npc = 105674, name = 'Varenne'},
Nenue@33 46 [41860] = {npc = 104970, name = 'Xorvasc'},
Nenue@33 47 [40299] = {npc = 99210, name = 'Bodhi Sunwayver'},
Nenue@33 48 [42442] = {npc = 107489, name = 'Amalia'},
Nenue@33 49 [40280] = {npc = 99077, name = 'Bredda Tenderhide'},
Nenue@33 50 [41687] = {npc = 104553, name = 'Odrogg'},
Nenue@33 51 [41944] = {npc = 105455, name = 'Trapper Jarrun'},
Nenue@33 52 [40337] = {npc = 97709, name = 'Master Tamer Flummox'},
Nenue@33 53 [40279] = {npc = 99035, name = 'Durian Strongfruit'}
Nenue@33 54 }
Nenue@33 55 local familiars_id = 9696
Nenue@33 56
Nenue@40 57 db.DefaultFilterType = {
Nenue@36 58 iconWidth = 24,
Nenue@40 59 iconHeight = 18,
Nenue@36 60 borderWidth = 3,
Nenue@36 61 highlightWidth = 2,
Nenue@30 62 TagSize = 12,
Nenue@30 63 TimeleftStage = 3,
Nenue@30 64 showNumber = true,
Nenue@30 65 numberFontObject = 'WorldPlanNumberFontThin'
Nenue@30 66 }
Nenue@93 67
Nenue@93 68 local headerNames = {
Nenue@93 69 ['rewardType'] = 'Reward Type',
Nenue@93 70 ['worldQuestType'] = 'Quest Type',
Nenue@93 71 ['isElite'] = 'Elite',
Nenue@93 72 ['factionID'] = 'Bounties'
Nenue@93 73 }
Nenue@93 74
Nenue@40 75 db.DefaultFilters = {
Nenue@30 76 { filterKey= 'rewardType', cVar = 'worldQuestFilterArtifactPower', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" },
Nenue@31 77 { filterKey= 'rewardType', cVar = 'worldQuestFilterOrderResources', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\Icons\\inv_orderhall_orderresources" },
Nenue@30 78 { filterKey= 'rewardType', cVar = 'worldQuestFilterEquipment', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" },
Nenue@30 79 { filterKey= 'rewardType', cVar = 'worldQuestFilterProfessionMaterials', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 },
Nenue@30 80 { filterKey= 'rewardType', cVar = 'worldQuestFilterGold', filterValue = REWARD_CASH, label = 'Gold', texture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" },
Nenue@30 81 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 },
Nenue@30 82 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", },
Nenue@93 83 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\BattlenetWorking0", },
Nenue@30 84 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", },
Nenue@93 85 --{ filterKey = 'isElite', filterValue = true, label = 'Elite', texture = "", desaturated = false},
Nenue@93 86 --{ filterKey = 'isElite', filterValue = false, label = 'Not-Elite', texture = "", desaturated = false},
Nenue@30 87 }
Nenue@30 88 local defaults = {}
Nenue@30 89
Nenue@108 90 WorldPlanSummaryMixin = {
Nenue@108 91 fadeOpacity = 1,
Nenue@108 92 }
Nenue@41 93 local Module = WorldPlanSummaryMixin
Nenue@41 94 Module.selectedBountyIndex = {}
Nenue@41 95 Module.bounties = {}
Nenue@41 96 Module.filterList = {}
Nenue@93 97 Module.Buttons = {}
Nenue@93 98 Module.Headers = {}
Nenue@41 99 Module.cvarFiltersDirty = false
Nenue@93 100 WorldPlanFilterButtonMixin = {}
Nenue@93 101 local Pin = WorldPlanFilterButtonMixin
Nenue@30 102
Nenue@41 103 function Module:OnLoad()
Nenue@93 104 --self:SetParent(WorldMapFrame.UIElementsFrame)
Nenue@40 105 WorldPlan:AddHandler(self)
Nenue@69 106 --[[for index, info in ipairs(db.DefaultFilters) do
Nenue@40 107 info.zone = db.DefaultFilterType
Nenue@40 108 info.continent = db.DefaultFilterType
Nenue@30 109 info.pinMask = "Interface\\Minimap\\UI-Minimap-Background"
Nenue@30 110 WorldPlan:AddTypeInfo(self,index, info)
Nenue@30 111 end
Nenue@69 112 --]]
Nenue@93 113
Nenue@93 114
Nenue@30 115 end
Nenue@30 116
Nenue@30 117
Nenue@57 118 function Module:OnEvent(event, arg)
Nenue@33 119 print('|cFF00FF88'..self:GetName()..':OnEvent()', event)
Nenue@57 120 if (event == 'QUEST_LOG_UPDATE') and arg then
Nenue@93 121 filtersDirty = true
Nenue@93 122 self:Refresh()
Nenue@57 123 end
Nenue@30 124 end
Nenue@30 125
Nenue@30 126 local bountyIndex
Nenue@30 127 local debug_headers = {}
Nenue@93 128 local ToggleButton = {}
Nenue@41 129 function Module:Setup()
Nenue@33 130 print('|cFF00FF88'..self:GetName()..':Setup()')
Nenue@45 131 self.isStale = true
Nenue@93 132 self:SetParent(WorldMapFrame.UIElementsFrame)
Nenue@93 133 --self:SetPoint('BOTTOMLEFT')
Nenue@93 134 for k,v in pairs( ToggleButton) do
Nenue@93 135 self.Toggle:SetScript(k,v)
Nenue@93 136 end
Nenue@93 137 self.Toggle:SetSize(TOGGLE_SIZE, TOGGLE_SIZE)
Nenue@93 138
Nenue@30 139 end
Nenue@30 140
Nenue@30 141
Nenue@93 142 function Module:OnUpdate(sinceLast)
Nenue@33 143 if self.isStale then
Nenue@93 144 print('|cFF00FF00pushing update')
Nenue@33 145 self:Refresh()
Nenue@33 146 end
Nenue@93 147
Nenue@93 148 barMouseOver = self:IsMouseOver()
Nenue@108 149 self:UpdateAlpha(sinceLast, barMouseOver)
Nenue@30 150 end
Nenue@33 151
Nenue@84 152 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
Nenue@84 153 print('|cFFFFFF00OnMapInfo()', isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
Nenue@41 154 if not isBrokenIsle then
Nenue@41 155 self:SetShown(false)
Nenue@41 156 else
Nenue@93 157 self:SetShown(true)
Nenue@93 158 if isMapOpen then
Nenue@84 159 self:Refresh()
Nenue@93 160 else
Nenue@93 161 matchesDirty = true
Nenue@93 162 layoutDirty = true
Nenue@84 163 end
Nenue@41 164 end
Nenue@41 165 end
Nenue@41 166
Nenue@41 167 function Module:OnShow()
Nenue@33 168 print('|cFF00FF88'..self:GetName()..':OnShow()')
Nenue@93 169 self:Refresh()
Nenue@93 170 end
Nenue@93 171
Nenue@93 172 local IsBountyCriteria = function(poiFrame, questID)
Nenue@93 173 return IsQuestCriteriaForBounty(poiFrame.questID, questID)
Nenue@93 174 end
Nenue@93 175
Nenue@93 176 local tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID = tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID
Nenue@93 177
Nenue@93 178 function Module:OnConfigUpdate()
Nenue@93 179
Nenue@93 180 ToggleButton.OnShow(self.Toggle)
Nenue@93 181 end
Nenue@93 182
Nenue@93 183 function Module:Reset()
Nenue@95 184
Nenue@95 185
Nenue@95 186
Nenue@93 187 self:UpdateFilters('SUMMARY_RESET')
Nenue@93 188 self:UpdateMatches('SUMMARY_RESET')
Nenue@93 189 self:UpdateLayout('SUMMARY_RESET')
Nenue@93 190 end
Nenue@93 191
Nenue@93 192 function Module:Refresh()
Nenue@93 193 self:UpdateFilters('SUMMARY_REFRESH')
Nenue@93 194 self:UpdateMatches('SUMMARY_REFRESH')
Nenue@93 195 self:UpdateLayout('SUMMARY_REFRESH')
Nenue@93 196 end
Nenue@93 197
Nenue@93 198 local questResults = {{} }
Nenue@93 199 db.FilterList = {}
Nenue@93 200
Nenue@93 201 function Module:UpdateFilters(event)
Nenue@93 202
Nenue@93 203 print('|cFF00FFFF'..self:GetName()..':GetFilters()', event)
Nenue@93 204
Nenue@93 205 wipe(db.FilterList)
Nenue@93 206
Nenue@93 207 for index, info in ipairs(db.DefaultFilters) do
Nenue@95 208 info.used = true
Nenue@93 209 tinsert(db.FilterList, info)
Nenue@93 210 end
Nenue@93 211 self.bounties = db.Bounties
Nenue@93 212 self.BountyFilters = {}
Nenue@95 213 local numBounties = 0
Nenue@93 214 for index, data in ipairs(self.bounties) do
Nenue@93 215 if not IsQuestComplete(data.questID) then
Nenue@95 216 numBounties = numBounties + 1
Nenue@93 217 local info = self.BountyFilters[index]
Nenue@93 218 if not info then
Nenue@93 219 info = {}
Nenue@93 220 self.BountyFilters[index] = info
Nenue@93 221 layoutDirty = true
Nenue@93 222 else
Nenue@93 223 if info.questID ~= data.questID then
Nenue@93 224 layoutDirty = true
Nenue@93 225 end
Nenue@93 226 end
Nenue@93 227
Nenue@93 228 local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID))
Nenue@95 229 info.used = true
Nenue@93 230 info.filterKey = 'factionID'
Nenue@93 231 info.filterFunc = IsBountyCriteria
Nenue@93 232 info.filterValue = data.questID
Nenue@93 233 info.label = questTitle
Nenue@93 234 info.texture = data.icon
Nenue@93 235 print('loading emissary', questTitle)
Nenue@93 236
Nenue@93 237 tinsert(db.FilterList, info)
Nenue@93 238 --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
Nenue@93 239 end
Nenue@95 240 end
Nenue@93 241
Nenue@95 242 for i = numBounties + 1, #self.BountyFilters do
Nenue@95 243 self.BountyFilters[i].used = nil
Nenue@32 244 end
Nenue@95 245
Nenue@32 246 end
Nenue@30 247
Nenue@93 248 function Module:UpdateMatches(event)
Nenue@93 249 print('|cFF00FF00UpdateMatches()', event)
Nenue@93 250 local quests = db.QuestsByID
Nenue@93 251 local questsForMap = db.QuestsByZone[db.currentMapID] or quests
Nenue@30 252
Nenue@93 253 for index, info in ipairs(db.FilterList) do
Nenue@93 254 info.GlobalMatches = info.GlobalMatches or {}
Nenue@93 255 info.LocalMatches = info.LocalMatches or {}
Nenue@93 256 wipe(info.GlobalMatches)
Nenue@93 257 wipe(info.LocalMatches)
Nenue@93 258 print(info.filterKey, info.filterValue, info.filterFunc and 'func test' or 'compare')
Nenue@93 259 for questID, pin in pairs(quests) do
Nenue@93 260 print('', questID, pin.dataLoaded, (not IsQuestComplete(questID)))
Nenue@95 261 if pin.dataLoaded and (not IsQuestComplete(questID)) then
Nenue@93 262 local keyName, keyValue = info.filterKey, info.filterValue
Nenue@93 263 local isMatch
Nenue@93 264 if info.filterFunc then
Nenue@93 265 isMatch = info.filterFunc(pin, keyValue)
Nenue@93 266 print(' running special function, result =', isMatch)
Nenue@93 267 elseif pin[keyName] and (pin[keyName] == keyValue) then
Nenue@93 268 isMatch = true
Nenue@93 269 print(' rote match')
Nenue@93 270 end
Nenue@93 271 if isMatch then
Nenue@93 272 tinsert(info.GlobalMatches, pin)
Nenue@93 273 if questsForMap[questID] then
Nenue@93 274 print(' local map')
Nenue@93 275 tinsert(info.LocalMatches, pin)
Nenue@93 276 end
Nenue@93 277 end
Nenue@93 278 end
Nenue@30 279 end
Nenue@93 280 print('global', #info.GlobalMatches, 'local', #info.LocalMatches)
Nenue@30 281 end
Nenue@30 282 end
Nenue@30 283
Nenue@93 284 function Module:UpdateLayout(event)
Nenue@93 285 print('|cFF00FF88UpdateLayout()|r', event, 'currentMap=',db.currentMapID)
Nenue@30 286
Nenue@93 287 self.filtersSelected = nil
Nenue@30 288
Nenue@93 289 local currentHeader
Nenue@93 290 local relativeFrame = self
Nenue@93 291 local lastKey
Nenue@31 292
Nenue@93 293 local numHeaders = 0
Nenue@93 294 local numButtons = 0
Nenue@40 295
Nenue@93 296 local layoutWidth = TOGGLE_SIZE + HEADERS_SPACING * 2
Nenue@93 297 local headerWidth = HEADERS_SPACING
Nenue@30 298
Nenue@40 299
Nenue@40 300 local layout = db.DefaultFilterType
Nenue@36 301 local borderWidth = layout.iconWidth + (layout.borderWidth * 2)
Nenue@36 302 local highlightWidth = borderWidth + (layout.highlightWidth * 2)
Nenue@40 303 local mapQuests = db.QuestsByZone[db.currentMapID] or db.QuestsByID
Nenue@84 304 local n = 0
Nenue@84 305 for _ in pairs(mapQuests) do
Nenue@84 306 n = n + 1
Nenue@84 307 end
Nenue@84 308 print(n, 'pins to work with')
Nenue@84 309
Nenue@93 310
Nenue@93 311 filtersUsed = nil
Nenue@57 312 local firstCvar, lastCvar
Nenue@93 313 local isFirst = true
Nenue@93 314 for index, info in ipairs(db.FilterList) do
Nenue@93 315 --print('num here', numQuestsHere, numQuestsTotal)
Nenue@40 316
Nenue@30 317
Nenue@40 318 --print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')')
Nenue@40 319
Nenue@93 320 if #info.GlobalMatches >= 1 then
Nenue@93 321 if info.filterKey ~= lastKey then
Nenue@93 322
Nenue@93 323 numHeaders = numHeaders + 1
Nenue@93 324 local nextHeader = self.Headers[numHeaders] or CreateFrame('Frame', 'FilterHeader' .. numHeaders, self, 'WorldPlanFilterHeader')
Nenue@93 325 if currentHeader then
Nenue@93 326 nextHeader:SetPoint('TOPLEFT', currentHeader, 'TOPRIGHT', 0, 0)
Nenue@93 327
Nenue@93 328 currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT)
Nenue@93 329 layoutWidth = layoutWidth + headerWidth
Nenue@93 330 headerWidth = HEADERS_SPACING
Nenue@93 331 else
Nenue@93 332 nextHeader:SetPoint('TOPLEFT', TOGGLE_SIZE + HEADERS_SPACING * 2, 0)
Nenue@93 333
Nenue@93 334 end
Nenue@93 335
Nenue@93 336 print(' begin header '..numHeaders, 'layout width =', floor(layoutWidth+.5))
Nenue@93 337 isFirst = true
Nenue@93 338 currentHeader = nextHeader
Nenue@93 339 currentHeader.Backdrop:SetHeight(BUTTONS_HEIGHT *2)
Nenue@93 340 currentHeader.Label:SetText(headerNames[info.filterKey])
Nenue@93 341 relativeFrame = currentHeader
Nenue@93 342 end
Nenue@93 343
Nenue@93 344 numButtons = numButtons + 1
Nenue@93 345 local button = self.Buttons[numButtons]
Nenue@93 346 if not button then
Nenue@93 347 button = CreateFrame('Button', 'FilterButton'..numButtons, self, 'WorldPlanFilterButton')
Nenue@93 348 button:SetSize(32,BUTTONS_HEIGHT)
Nenue@93 349 button.icon:SetTexCoord(0.1,.9,.1,(1 * (BUTTONS_HEIGHT/32)))
Nenue@30 350
Nenue@40 351 button.RewardBorder:ClearAllPoints()
Nenue@40 352 button.RewardBorder:SetPoint('TOPLEFT', button, 'TOPLEFT')
Nenue@40 353 button.RewardBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT')
Nenue@30 354 end
Nenue@30 355
Nenue@30 356 button.info = info
Nenue@93 357 button.numQuestsTotal = #info.GlobalMatches
Nenue@93 358 button.numQuestsHere = #info.LocalMatches
Nenue@93 359 button.GlobalMatches = info.GlobalMatches
Nenue@93 360 button.LocalMatches = info.LocalMatches
Nenue@93 361 button.isFirst = isFirst
Nenue@30 362 button:SetID(index)
Nenue@93 363 button:SetParent(currentHeader)
Nenue@30 364 button.relativeFrame = relativeFrame
Nenue@40 365 button:Refresh()
Nenue@30 366 button:Show()
Nenue@30 367 relativeFrame = button
Nenue@93 368 headerWidth = headerWidth + button:GetWidth() + BUTTONS_SPACING
Nenue@40 369
Nenue@93 370 isFirst = false
Nenue@40 371 if info.cVar then
Nenue@40 372 firstCvar = firstCvar or button
Nenue@40 373 lastCvar = button
Nenue@40 374 end
Nenue@93 375 lastKey = info.filterKey
Nenue@30 376 end
Nenue@30 377 end
Nenue@30 378
Nenue@30 379 self.numHeaders = numHeaders
Nenue@93 380 for i = numButtons + 1, #self.Buttons do
Nenue@93 381 if self.Buttons[i] then
Nenue@93 382 self.Buttons[i]:Hide()
Nenue@93 383 wipe(self.Buttons[i].LocalMatches)
Nenue@93 384 wipe(self.Buttons[i].GlobalMatches)
Nenue@93 385 end
Nenue@93 386 end
Nenue@93 387 for i = numHeaders + 1, #self.Headers do
Nenue@93 388 if self.Headers[i] then
Nenue@93 389 self.Headers[i]:Hide()
Nenue@31 390 end
Nenue@30 391 end
Nenue@40 392
Nenue@40 393
Nenue@93 394 if currentHeader then
Nenue@93 395 currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT)
Nenue@93 396 layoutWidth = layoutWidth + headerWidth + HEADERS_SPACING
Nenue@93 397 end
Nenue@40 398
Nenue@95 399 self:SetSize(layoutWidth, BUTTONS_HEIGHT + (BUTTONS_SPACING * 2))
Nenue@93 400 self:ClearAllPoints()
Nenue@108 401 self:SetPoint('TOPLEFT', WorldMapFrameNavBar, 'BOTTOMLEFT', 0, -3)
Nenue@32 402 self.isStale = nil
Nenue@93 403 layoutDirty = nil
Nenue@30 404 end
Nenue@30 405
Nenue@41 406 function Module:Cleanup()
Nenue@30 407 -- hide trailing buttons
Nenue@30 408 end
Nenue@30 409
Nenue@93 410 local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF' }
Nenue@93 411 local found = {}
Nenue@41 412 function Pin:OnEnter()
Nenue@93 413 if #self.GlobalMatches >= 1 then
Nenue@93 414 GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
Nenue@108 415 GameTooltip:AddLine(headerNames[self.info.filterKey])
Nenue@31 416 GameTooltip:AddLine(self.info.label)
Nenue@93 417 wipe(found)
Nenue@93 418
Nenue@93 419 if self.numQuestsHere >= 1 then
Nenue@93 420 if self.numQuestsHere < self.numQuestsTotal then
Nenue@93 421 GameTooltip:AddLine('This Zone', 1, 1, 0)
Nenue@93 422 end
Nenue@93 423 for index, pin in ipairs(self.LocalMatches) do
Nenue@93 424 local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
Nenue@93 425 found[pin] = pin
Nenue@93 426 GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 0, 1, 0)
Nenue@93 427 end
Nenue@31 428 end
Nenue@93 429
Nenue@93 430 if self.numQuestsHere < self.numQuestsTotal then
Nenue@93 431 if self.numQuestsHere >= 1 then
Nenue@93 432 GameTooltip:AddLine(' ')
Nenue@93 433 end
Nenue@93 434 GameTooltip:AddLine('Other Maps', 1, 1, 0)
Nenue@93 435 for index, pin in ipairs(self.GlobalMatches) do
Nenue@93 436 if not found[pin] then
Nenue@93 437 local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite
Nenue@93 438 found[pin] = pin
Nenue@93 439 GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 1, 1, 1)
Nenue@93 440 end
Nenue@93 441 end
Nenue@93 442 end
Nenue@93 443
Nenue@93 444
Nenue@40 445 GameTooltip:AddLine(self.numQuestsTotal .. ' total')
Nenue@36 446 GameTooltip:Show()
Nenue@31 447 end
Nenue@30 448 end
Nenue@30 449
Nenue@41 450 function Pin:OnLeave()
Nenue@31 451 if GameTooltip:IsOwned(self) then
Nenue@31 452 GameTooltip:Hide()
Nenue@31 453 end
Nenue@31 454 end
Nenue@30 455
Nenue@41 456 function Pin:Refresh()
Nenue@30 457 local info = self.info
Nenue@30 458 self.filterKey = info.filterKey
Nenue@30 459 self.filterValue = info.filterValue
Nenue@30 460 self.tagID = info.tagID
Nenue@30 461
Nenue@30 462 self.icon:SetTexture(info.texture)
Nenue@93 463
Nenue@93 464 if (self.numQuestsHere == 0) and (self.numQuestsTotal >= 1) then
Nenue@93 465 self.count:SetText('*'..self.numQuestsTotal)
Nenue@93 466 self.count:SetTextColor(0,1,1)
Nenue@93 467 elseif self.numQuestsHere < self.numQuestsTotal then
Nenue@93 468 self.count:SetText(self.numQuestsHere..'+')
Nenue@93 469 self.count:SetTextColor(1,1,0)
Nenue@93 470 else
Nenue@93 471 self.count:SetText(self.numQuestsHere)
Nenue@93 472 self.count:SetTextColor(1,1,1)
Nenue@93 473 end
Nenue@93 474
Nenue@30 475 self.cVar = info.cVar
Nenue@30 476 self.itemTexture = self.texture
Nenue@30 477
Nenue@45 478 self:ClearAllPoints()
Nenue@40 479 if self.isFirst then
Nenue@93 480 self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', HEADERS_SPACING, -HEADERS_SPACING)
Nenue@30 481 else
Nenue@93 482 self:SetPoint('LEFT', self.relativeFrame, 'RIGHT', BUTTONS_SPACING, 0)
Nenue@30 483 end
Nenue@93 484 --print('anchor', self.relativeFrame:IsShown(), self:GetPoint(1))
Nenue@30 485
Nenue@40 486 self.icon:SetDesaturated(self.numQuestsHere == 0)
Nenue@40 487
Nenue@40 488 local r, g, b, a = 0,0,0,1
Nenue@31 489 local desaturated = false
Nenue@93 490 if (self.numQuestsHere > 0) or db.UsedFilters[self.filterKey] then
Nenue@93 491
Nenue@40 492 if self.cVar then
Nenue@40 493 if GetCVarBool(self.cVar) then
Nenue@93 494 --self.count:SetTextColor(1,1,1)
Nenue@41 495 r,g,b,a = 0, 0, 0, 1
Nenue@31 496 else
Nenue@93 497 filtersUsed = true
Nenue@93 498 --self.count:SetTextColor(1,0,0)
Nenue@40 499 self.icon:SetDesaturated(true)
Nenue@41 500 r,g,b,a = 1, 0, 0, 0.5
Nenue@31 501 end
Nenue@31 502 else
Nenue@40 503 if db.UsedFilters[self.filterKey] then
Nenue@93 504 filtersUsed = true
Nenue@40 505 if db.UsedFilters[self.filterKey] == self.filterValue then
Nenue@93 506 --self.count:SetTextColor(0,1,0)
Nenue@41 507 r, g, b = 0, 1, 0
Nenue@40 508 else
Nenue@93 509 --self.count:SetTextColor(1,0,0)
Nenue@40 510 r, g, b = 1, 0, 0
Nenue@40 511 end
Nenue@36 512 else
Nenue@36 513
Nenue@93 514 --self.count:SetTextColor(1,1,1)
Nenue@40 515 if self.filterKey == 'worldQuestType' then
Nenue@40 516 r, g, b = 0, 0, 1
Nenue@40 517 elseif self.filterKey == 'factionID' then
Nenue@40 518 r, g, b = 1, 1, 0
Nenue@40 519 end
Nenue@36 520 end
Nenue@30 521 end
Nenue@30 522 end
Nenue@41 523 self.RewardBorder:SetColorTexture(r, g, b)
Nenue@41 524 self:SetAlpha(a)
Nenue@31 525
Nenue@30 526 --self:UpdateSize()
Nenue@30 527 end
Nenue@30 528
Nenue@41 529 function Pin:OnLoad()
Nenue@30 530 self:RegisterForClicks('AnyUp')
Nenue@30 531 self:SetFrameStrata('HIGH')
Nenue@30 532 self:SetFrameLevel(151)
Nenue@40 533 self.questList = {}
Nenue@41 534 -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
Nenue@30 535 end
Nenue@30 536
Nenue@41 537 function Pin:OnUpdate ()
Nenue@93 538 local group = self:GetParent()
Nenue@93 539 if group:IsMouseOver() and barMouseOver then
Nenue@93 540 group.Backdrop:Show()
Nenue@93 541 group.Label:Show()
Nenue@93 542 else
Nenue@93 543 group.Backdrop:Hide()
Nenue@93 544 group.Label:Hide()
Nenue@93 545 end
Nenue@30 546 end
Nenue@30 547
Nenue@30 548 -- shift-click: reset filter
Nenue@30 549 -- click: rotate through include(1), exclude(-1), ignore(nil)
Nenue@36 550 local filtered_report = {}
Nenue@40 551 local RESET_FILTER = "|cFFFFFFFF+%s|r"
Nenue@40 552 local FILTER_EXCLUDE_TYPE = '|cFFFF0000-%s|r'
Nenue@40 553 local FILTER_INCLUDE_TYPE = '|cFF00FF00+%s|r'
Nenue@41 554 function Pin:OnClick (button)
Nenue@30 555
Nenue@30 556 local filterKey = self.filterKey
Nenue@30 557 local filterValue = self.filterValue
Nenue@36 558 local cVar = self.cVar
Nenue@36 559 local parent = self:GetParent()
Nenue@40 560 local setDirty
Nenue@40 561
Nenue@40 562 print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, cVar, parent)
Nenue@30 563
Nenue@36 564 local resetMode = (button == 'RightButton')
Nenue@36 565 wipe(filtered_report)
Nenue@36 566 if not (filterKey or cVar) then
Nenue@40 567 for i, info in ipairs(db.DefaultFilters) do
Nenue@33 568 if info.cVar then
Nenue@40 569 SetCVar(info.cVar, 1)
Nenue@40 570 elseif info.filterKey then
Nenue@40 571 if db.UsedFilters[info.filterKey] then
Nenue@40 572 db.UsedFilters[info.filterKey] = nil
Nenue@36 573 end
Nenue@33 574 end
Nenue@33 575 end
Nenue@40 576 parent.cvarFiltersDirty = false
Nenue@33 577
Nenue@40 578 --WorldPlan:print('All filters reset.')
Nenue@36 579 elseif cVar then
Nenue@40 580 if resetMode then
Nenue@40 581 print('|cFFFF4400cleaning dirty')
Nenue@40 582 for i, info in ipairs(db.DefaultFilters) do
Nenue@33 583 if info.cVar then
Nenue@40 584 parent.cvarFiltersDirty = false
Nenue@40 585 SetCVar(info.cVar, 1)
Nenue@33 586 end
Nenue@33 587 end
Nenue@40 588 --WorldPlan:print('Reward filters reset.')
Nenue@40 589 elseif parent.cvarFiltersDirty == true then
Nenue@40 590 if GetCVarBool(cVar) then
Nenue@40 591 tinsert(filtered_report, FILTER_EXCLUDE_TYPE:format(tostring(self.info.label)))
Nenue@40 592 SetCVar(cVar, 0)
Nenue@40 593 else
Nenue@40 594
Nenue@40 595 tinsert(filtered_report, FILTER_INCLUDE_TYPE:format(tostring(self.info.label)))
Nenue@40 596 SetCVar(cVar, 1)
Nenue@40 597 end
Nenue@40 598
Nenue@40 599 -- check the visible filters and consider it clean if they're all lit
Nenue@40 600 parent.cvarFiltersDirty = false
Nenue@93 601 for i, info in ipairs(db.FilterList) do
Nenue@93 602 if info.cVar and (#info.GlobalMatches >= 1) then
Nenue@40 603 print(info.cVar, GetCVarBool(info.cVar))
Nenue@40 604 if GetCVarBool(info.cVar) == false then
Nenue@40 605 parent.cvarFiltersDirty = true
Nenue@40 606 print('|cFFFF4400still dirty')
Nenue@40 607 break
Nenue@40 608 end
Nenue@40 609 end
Nenue@36 610 end
Nenue@36 611 else
Nenue@40 612 print('|cFFFF4400making dirty')
Nenue@40 613 for i, info in ipairs(db.DefaultFilters) do
Nenue@40 614 if info.cVar then
Nenue@40 615 local msgType = (cVar == info.cVar) and FILTER_INCLUDE_TYPE or FILTER_EXCLUDE_TYPE
Nenue@40 616 SetCVar(info.cVar, ((cVar == info.cVar) and 1) or 0)
Nenue@40 617 tinsert(filtered_report, msgType:format(info.label))
Nenue@40 618 end
Nenue@40 619 end
Nenue@40 620 parent.cvarFiltersDirty = true
Nenue@36 621 end
Nenue@30 622 else
Nenue@40 623 if resetMode then
Nenue@40 624 wipe(db.UsedFilters)
Nenue@40 625 --WorldPlan:print('Type filters reset.')
Nenue@31 626 else
Nenue@40 627 if (db.UsedFilters[filterKey] == filterValue) or resetMode then
Nenue@40 628 db.UsedFilters[filterKey] = nil
Nenue@40 629 tinsert(filtered_report, FILTER_INCLUDE_TYPE:format(tostring(filterKey)))
Nenue@40 630 else
Nenue@40 631 db.UsedFilters[filterKey] = filterValue
Nenue@40 632 tinsert(filtered_report, FILTER_EXCLUDE_TYPE:format(tostring(filterKey)))
Nenue@40 633 end
Nenue@30 634 end
Nenue@30 635 end
Nenue@40 636 if #filtered_report >= 1 then
Nenue@40 637 --WorldPlan:print('Setting filter(s):', table.concat(filtered_report, ', '))
Nenue@40 638 end
Nenue@33 639 WorldPlan:Refresh(true)
Nenue@93 640 end
Nenue@93 641 function ToggleButton:OnEnter()
Nenue@93 642
Nenue@93 643 GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
Nenue@93 644 GameTooltip:AddLine('Toggle Pins')
Nenue@93 645 GameTooltip:Show()
Nenue@93 646 end
Nenue@93 647 function ToggleButton:OnLeave()
Nenue@93 648
Nenue@93 649 if GameTooltip:IsOwned(self) then
Nenue@93 650 GameTooltip:Hide()
Nenue@93 651 end
Nenue@93 652 end
Nenue@93 653 function ToggleButton:OnShow()
Nenue@93 654 self:SetChecked(db.Config.EnablePins and true or false)
Nenue@93 655 end
Nenue@93 656 function ToggleButton:OnHide()
Nenue@93 657 if GameTooltip:IsOwned(self) then
Nenue@93 658 GameTooltip:Hide()
Nenue@93 659 end
Nenue@93 660
Nenue@93 661 end
Nenue@93 662 function ToggleButton:OnClick()
Nenue@93 663 --print(self:GetChecked())
Nenue@93 664 db.Config.EnablePins = self:GetChecked()
Nenue@93 665 _G.WorldPlan:OnConfigUpdate()
Nenue@30 666 end