You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

457 lines
18 KiB

local myname, ns = ...
local _, myfullname = GetAddOnInfo(myname)
local LibDD = LibStub:GetLibrary("LibUIDropDownMenu-4.0")
ns.suppressoverlay = {}
local function hideTextureWithAtlas(atlas, ...)
for i=1, select("#", ...) do
local region = select(i, ...)
if region:IsObjectType("Texture") and region:GetAtlas() == atlas then
region:Hide()
end
end
end
local defaultSort = function(a, b) return a < b end
local function iterKeysByValue(tbl, sortFunction)
local keys = {}
for key in pairs(tbl) do
table.insert(keys, key)
end
table.sort(keys, function(a, b)
return (sortFunction or defaultSort)(tbl[a], tbl[b])
end)
return ipairs(keys)
end
local OptionsDropdown = {}
do
local inherited = {"set", "get", "func", "confirm", "validate", "disabled", "hidden"}
local function inherit(t1, t2)
for _,k in ipairs(inherited) do
if t2[k] ~= nil then
t1[k] = t2[k]
end
end
end
local nodet = {}
function OptionsDropdown.node(options, ...)
wipe(nodet)
local node = options
inherit(nodet, node)
for i=1, select('#', ...) do
node = node.args[select(i, ...)]
if not node then return end
inherit(nodet, node)
end
return ns.merge(nodet, node)
end
local info = {}
function OptionsDropdown.makeInfo(options, ...)
local node = OptionsDropdown.node(options, ...)
wipe(info)
info.options = options
info.option = node
info.arg = node.arg
info.type = node.type
info.handler = node.handler
info.uiType = "dropdown"
info.uiName = "HandyNotesTreasures-Dropdown"
info[0] = "" -- not a slashcommand
for i=1, select('#', ...) do
info[i] = select(i, ...)
end
return info
end
local function nodeValueOrFunc(key, options, ...)
local node = OptionsDropdown.node(options, ...)
if not node then return end
if type(node[key]) == "function" then
return node[key](OptionsDropdown.makeInfo(options, ...))
end
return node[key]
end
function OptionsDropdown.isHidden(options, ...)
return nodeValueOrFunc('hidden', options, ...)
end
function OptionsDropdown.values(options, ...)
return nodeValueOrFunc('values', options, ...)
end
end
local zoneGroups, zoneHasGroups, zoneAchievements, zoneHasAchievements, allGroups, hasGroups
do
local gcache
function allGroups()
if not gcache then
gcache = {}
for _, points in pairs(ns.points) do
for _, point in pairs(points) do
if point.group then
gcache[point.group] = point.group
end
end
end
end
return gcache
end
function hasGroups()
local groups = allGroups()
for _ in pairs(groups) do
return true
end
end
local zcache = {}
function zoneGroups(uiMapID)
if not zcache[uiMapID] then
local relevant = {}
for _, point in pairs(ns.points[uiMapID] or {}) do
if point.group then
relevant[point.group] = point.group
end
end
zcache[uiMapID] = relevant
end
return zcache[uiMapID]
end
function zoneHasGroups(uiMapID)
for _, _ in pairs(zoneGroups(uiMapID)) do
return true
end
end
local acache = {}
function zoneAchievements(uiMapID)
if not acache[uiMapID] then
local relevant = {}
for _, point in pairs(ns.points[uiMapID] or {}) do
if point.achievement then
relevant[point.achievement] = true
end
end
acache[uiMapID] = relevant
end
return acache[uiMapID]
end
function zoneHasAchievements(uiMapID)
for _, _ in pairs(zoneAchievements(uiMapID)) do
return true
end
end
end
function ns.SetupMapOverlay()
local frame
local Krowi = LibStub("Krowi_WorldMapButtons-1.4", true) or LibStub("Krowi_WorldMapButtons-1.3", true)
if Krowi then
frame = Krowi:Add("WorldMapTrackingOptionsButtonTemplate", "DROPDOWNTOGGLEBUTTON")
elseif false and WorldMapFrame.AddOverlayFrame then
-- retail
-- This is super-tainted on retail, so is currently disabled
frame = WorldMapFrame:AddOverlayFrame("WorldMapTrackingOptionsButtonTemplate", "DROPDOWNTOGGLEBUTTON", "TOPRIGHT", WorldMapFrame:GetCanvasContainer(), "TOPRIGHT", -68, -2)
else
-- classic!
-- (this is a close translation of WorldMapTrackingOptionsButtonTemplate)
frame = CreateFrame("DropDownToggleButton", WorldMapFrame, WorldMapFrame:GetCanvasContainer())
frame:SetFrameStrata(WorldMapFrame:GetFrameStrata() or "HIGH")
frame:SetSize(32, 32)
frame.Background = frame:CreateTexture(nil, "BACKGROUND")
frame.Background:SetPoint("TOPLEFT", 2, -4)
frame.Background:SetSize(25, 25)
frame.Background:SetTexture([[Interface\Minimap\UI-Minimap-Background]])
frame.Icon = frame:CreateTexture(nil, "ARTWORK")
frame.Icon:SetTexture([[Interface\Minimap\Tracking\None]])
frame.Icon:SetSize(20, 20)
frame.Icon:SetPoint("TOPLEFT", 6, -6)
frame.IconOverlay = frame:CreateTexture(nil, "OVERLAY")
frame.IconOverlay:Hide()
frame.IconOverlay:SetPoint("TOPLEFT", frame.Icon)
frame.IconOverlay:SetPoint("BOTTOMRIGHT", frame.Icon)
frame.IconOverlay:SetColorTexture(0, 0, 0, 0.5)
frame.Border = frame:CreateTexture(nil, "OVERLAY", nil, -1)
frame.Border:SetTexture([[Interface\Minimap\MiniMap-TrackingBorder]])
frame.Border:SetSize(54, 54)
frame.Border:SetPoint("TOPLEFT")
frame:SetHighlightTexture([[Interface\Minimap\UI-Minimap-ZoomButton-Highlight]], "ADD")
frame:SetPoint("TOPRIGHT", -68, -2)
hooksecurefunc(WorldMapFrame, "OnMapChanged", function()
frame:Refresh()
end)
end
-- replace the default dropdown:
frame.DropDown = LibDD:Create_UIDropDownMenu(myname .. "OptionsDropdown", frame) -- replace the template
frame.Icon:SetAtlas("VignetteLootElite")
frame.Icon:SetPoint("TOPLEFT", 6, -5)
hideTextureWithAtlas("MapCornerShadow-Right", frame:GetRegions())
frame.Refresh = function(self)
local uiMapID = WorldMapFrame.mapID
local info = C_Map.GetMapInfo(uiMapID)
local parentMapID = info and info.parentMapID or 0
if ns.db.worldmapoverlay and (
(ns.points[uiMapID] and not ns.suppressoverlay[uiMapID]) or
(ns.points[parentMapID] and not ns.suppressoverlay[parentMapID])
) then
self:Show()
else
self:Hide()
end
end
frame.OnMouseDown = function(self, button)
self.Icon:SetPoint("TOPLEFT", 8, -8);
self.IconOverlay:Show()
local uiMapID = WorldMapFrame.mapID
if not uiMapID then
return
end
LibDD:ToggleDropDownMenu(1, nil, self.DropDown, self, 0, -5)
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
end
frame.OnMouseUp = function(self)
self.Icon:SetPoint("TOPLEFT", 6, -5)
self.IconOverlay:Hide()
end
frame.OnMouseEnter = function(self)
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip_SetTitle(GameTooltip, myfullname)
GameTooltip_AddNormalLine(GameTooltip, "Adjust display settings")
GameTooltip:Show()
end
frame:SetScript("OnMouseUp", frame.OnMouseUp)
frame:SetScript("OnMouseDown", frame.OnMouseDown)
frame:SetScript("OnEnter", frame.OnMouseEnter)
frame:SetScript("OnLeave", GameTooltip_Hide)
frame.InitializeDropDown = function(self, level, menuList)
local uiMapID = WorldMapFrame.mapID
local info = LibDD:UIDropDownMenu_CreateInfo()
level = level or 1
if level == 1 then
info.isTitle = true
info.notCheckable = true
info.text = DISPLAY_OPTIONS
LibDD:UIDropDownMenu_AddButton(info, level)
info.isTitle = nil
info.disabled = nil
info.notCheckable = nil
info.isNotRadio = true
info.keepShownOnClick = true
info.tooltipOnButton = true
info.func = function(button)
local checked = button.checked
local value = button.value
if (checked) then
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
else
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF)
end
local option = ns.options.args.display.args[value]
local db = ns.db
if option.type == "execute" then
option.func()
else
db[value] = checked
end
ns.HL:Refresh()
end
local sorted = {}
for key in pairs(ns.options.args.display.args) do
table.insert(sorted, key)
end
table.sort(sorted, function(a, b)
return (ns.options.args.display.args[a].order or 0) < (ns.options.args.display.args[b].order or 0)
end)
for _, key in ipairs(sorted) do
local option = ns.options.args.display.args[key]
info.text = option.name
info.tooltipTitle = option.desc
info.value = key
if option.type == "toggle" then
info.notCheckable = nil
info.checked = ns.db[key]
elseif option.type == "execute" then
info.notCheckable = true
info.checked = nil
end
if option.disabled then
info.disabled = option.disabled()
else
info.disabled = nil
end
LibDD:UIDropDownMenu_AddButton(info, level)
end
LibDD:UIDropDownMenu_AddSeparator(level)
if not (ns.hiddenConfig.groupsHiddenByZone and OptionsDropdown.isHidden(ns.options, "groupsHidden")) and zoneHasGroups(uiMapID) then
local global = ns.hiddenConfig.groupsHiddenByZone
wipe(info)
info.isNotRadio = true
info.keepShownOnClick = true
info.tooltipOnButton = true
info.func = function(button, group)
if global then
ns.db.groupsHidden[group] = not button.checked
else
ns.db.groupsHiddenByZone[uiMapID][group] = not button.checked
end
ns.HL:Refresh()
end
info.tooltipTitle = global and "Hide this type of point everywhere" or "Hide this type of point on this map"
for _, group in iterKeysByValue(zoneGroups(uiMapID)) do
info.text = ns.render_string(ns.groups[group] or group)
info.arg1 = group
if global then
info.checked = not ns.db.groupsHidden[group]
else
info.checked = not ns.db.groupsHiddenByZone[uiMapID][group]
end
LibDD:UIDropDownMenu_AddButton(info, level)
end
end
if not OptionsDropdown.isHidden(ns.options, "achievementsHidden") and zoneHasAchievements(uiMapID) then
wipe(info)
info.isNotRadio = true
info.keepShownOnClick = true
info.tooltipOnButton = true
info.func = function(button, achievementid)
ns.db.achievementsHidden[achievementid] = not button.checked
ns.HL:Refresh()
end
info.tooltipTitle = "Hide this type of point"
for achievementid in pairs(zoneAchievements(uiMapID)) do
info.text = ns.render_string(("{achievement:%d}"):format(achievementid))
info.arg1 = achievementid
info.checked = not ns.db.achievementsHidden[achievementid]
LibDD:UIDropDownMenu_AddButton(info, level)
end
end
wipe(info)
info.hasArrow = true
info.keepShownOnClick = true
info.notCheckable = true
local displayed = false
if not OptionsDropdown.isHidden(ns.options, "achievementsHidden") then
info.text = ACHIEVEMENTS
info.value = "achievementsHidden"
LibDD:UIDropDownMenu_AddButton(info, level)
displayed = true
end
if not OptionsDropdown.isHidden(ns.options, "zonesHidden") then
info.text = ZONE
info.value = "zonesHidden"
LibDD:UIDropDownMenu_AddButton(info, level)
displayed = true
end
if not OptionsDropdown.isHidden(ns.options, "groupsHidden") and hasGroups() then
info.text = GROUP
info.value = "groupsHidden"
LibDD:UIDropDownMenu_AddButton(info, level)
displayed = true
end
if displayed then
LibDD:UIDropDownMenu_AddSeparator(level)
end
info.text = "Open HandyNotes options"
info.hasArrow = nil
info.keepShownOnClick = nil
info.func = function(button)
if InterfaceOptionsFrame_Show then
InterfaceOptionsFrame_Show()
InterfaceOptionsFrame_OpenToCategory('HandyNotes')
else
Settings.OpenToCategory('HandyNotes')
end
LibStub('AceConfigDialog-3.0'):SelectGroup('HandyNotes', 'plugins', myname:gsub("HandyNotes_", ""))
end
LibDD:UIDropDownMenu_AddButton(info, level)
elseif level == 2 or level == 3 then
local parent = L_UIDROPDOWNMENU_MENU_VALUE
local currentZone = WorldMapFrame.mapID
info.arg1 = parent
info.isTitle = nil
info.disabled = nil
info.notCheckable = nil
info.isNotRadio = true
info.keepShownOnClick = true
info.tooltipOnButton = true
info.func = function(button, section, subsection, checked)
local value = button.value
if (checked) then
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
else
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF)
end
if subsection then
ns.db[section][subsection][value] = not checked
else
ns.db[section][value] = not checked
end
ns.HL:Refresh()
end
local values = OptionsDropdown.values(ns.options, parent)
if parent == "achievementsHidden" then
local relevant = zoneAchievements(currentZone)
for _, achievementid in iterKeysByValue(values) do
info.text = values[achievementid]
info.value = achievementid
info.checked = not ns.db.achievementsHidden[achievementid]
if relevant[achievementid] then
info.text = BRIGHTBLUE_FONT_COLOR:WrapTextInColorCode(info.text) .. " " .. CreateAtlasMarkup("VignetteKill", 0)
end
LibDD:UIDropDownMenu_AddButton(info, level)
end
elseif parent == "zonesHidden" then
for _, uiMapID in iterKeysByValue(values) do
info.text = values[uiMapID]
info.value = uiMapID
info.checked = not ns.db.zonesHidden[uiMapID]
if uiMapID == currentZone then
info.text = BRIGHTBLUE_FONT_COLOR:WrapTextInColorCode(info.text) .. " " .. CreateAtlasMarkup("VignetteKill", 0)
end
if not ns.hiddenConfig.groupsHiddenByZone and zoneHasGroups(uiMapID) then
info.hasArrow = true
info.menuList = "groupsHiddenByZone"
else
info.hasArrow = nil
info.menuList = nil
end
LibDD:UIDropDownMenu_AddButton(info, level)
end
elseif parent == "groupsHidden" then
info.arg1 = "groupsHidden"
info.tooltipTitle = "Hide this type of point everywhere"
local groups = allGroups()
for _, group in iterKeysByValue(groups) do
info.text = ns.render_string(ns.groups[group] or group)
info.value = group
info.checked = not ns.db.groupsHidden[group]
LibDD:UIDropDownMenu_AddButton(info, level)
end
elseif menuList == "groupsHiddenByZone" then
local uiMapID = parent
info.arg1 = "groupsHiddenByZone"
info.arg2 = uiMapID
info.tooltipTitle = "Hide this type of point on this map"
local groups = zoneGroups(uiMapID)
for _, group in iterKeysByValue(groups) do
info.text = ns.render_string(ns.groups[group] or group)
info.value = group
info.checked = not ns.db.groupsHiddenByZone[uiMapID][group]
LibDD:UIDropDownMenu_AddButton(info, level)
end
end
end
end
frame.OnSelection = function(self, value, checked, arg1, arg2) end
LibDD:UIDropDownMenu_SetInitializeFunction(frame.DropDown, function(self, ...) frame:InitializeDropDown(...) end)
LibDD:UIDropDownMenu_SetDisplayMode(frame.DropDown, "MENU")
end