Mercurial > wow > worldplan
view FilterBar.lua @ 36:21bcff08b0f4
WorldPlan:
- Quest pins are now placed on the flight map. Their visibility rules will mirror the filter options from the world map.
- Filter controls polish:
- First click negates other reward type filters. Subsequent clicks will then toggle individual reward types until the filters are reset via Right-click.
- Adheres to the Blizzard CVars added in patch 7.1
- Numerous optimizations to how data and visual updates are handled; should see an even better load time, and snappier world map interaction.
ClassPlan:
- The 'Available Missions' list is now recorded. It can be reviewed by clicking on the mission list heading.
- Information filtering by character and realm.
author | Nenue |
---|---|
date | Fri, 04 Nov 2016 01:40:39 -0400 |
parents | be4db60219ca |
children | 589c444d4837 |
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 = { iconWidth = 24, borderWidth = 3, highlightWidth = 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 layout = DEFAULT_FILTER_LAYOUT local borderWidth = layout.iconWidth + (layout.borderWidth * 2) local highlightWidth = borderWidth + (layout.highlightWidth * 2) 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(borderWidth, borderWidth) button.icon:SetSize(layout.iconWidth, layout.iconWidth) button.RewardBorder:SetSize(borderWidth, borderWidth) button.HighlightBorder:SetSize(highlightWidth, highlightWidth) button.RewardBorder:SetMask(filterMask) button.RewardBorder:SetDesaturated(true) button.HighlightBorder:Hide() blocks[numHeaders] = button end button.info = info button.questList = questResults[resultIndex] button:SetID(index) button.spacing = ((relativeFrame.cVar and (not info.cVar)) or (relativeFrame.filterKey ~= info.filterKey)) and 5 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: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 ' .. pin.title ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b) end GameTooltip:Show() 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, -(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.RewardBorder: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.RewardBorder:SetVertexColor(0, 1, 0) else self.RewardBorder:SetVertexColor(1, 0, 0) end else if self.filterKey == 'worldQuestType' then self.RewardBorder:SetVertexColor(0, 1, 1) elseif self.filterKey == 'factionID' then self.RewardBorder:SetVertexColor(1, 1, 0) else self.RewardBorder:SetVertexColor(0.5, 0.5, 0.5) end end end --self:UpdateSize() end function WorldPlanFilterPinMixin:OnLoad() self:RegisterForClicks('AnyUp') self:SetFrameStrata('HIGH') self:SetFrameLevel(151) self:SetScript('OnUpdate', nil) WorldPlanPOIMixin.OnLoad(self) 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) local filtered_report = {} function WorldPlanFilterPinMixin:OnClick (button) print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, operation) local filterKey = self.filterKey local filterValue = self.filterValue local cVar = self.cVar local parent = self:GetParent() local operation = opPrefix local setDirty = false local resetMode = (button == 'RightButton') wipe(filtered_report) if not (filterKey or cVar) then wipe(WorldPlan.UsedFilters) for i, info in ipairs(DEFAULT_FILTER_LIST) do if info.cVar then if GetCVar(info.cVar) ~= 1 then tinsert(filtered_report, '|cFF888888'.. tostring(info.label) ..'|r') end SetCVar(info.cVar, 1) end end elseif cVar then WorldPlan:print('Toggling cvar filter:', cVar) if (not parent.isDirty) or resetMode then for i, info in ipairs(DEFAULT_FILTER_LIST) do if info.cVar then local value = GetCVar(info.cVar) if resetMode then value = 1 parent.isDirty = nil else if (cVar ~= info.cVar) then value = 0 else value = 1 end setDirty = true end SetCVar(info.cVar, value) end end if setDirty then parent.isDirty = true end else SetCVar(cVar, (GetCVarBool(cVar) and 0) or 1) end else local flushValue print('') if WorldPlan.UsedFilters[filterKey] == filterValue then WorldPlan.UsedFilters[filterKey] = nil tinsert(filtered_report, '|cFFFF0000'.. tostring(filterKey) ..'|r') else WorldPlan.UsedFilters[filterKey] = filterValue tinsert(filtered_report, '|cFF00FF00'.. tostring(filterKey) ..'|r') end end WorldPlan:print('Changed:', table.concat(filtered_report, ', ')) WorldPlan:Refresh(true) end