James D. Callahan III [07-10-10 - 05:13]
diff --git a/Frame.lua b/Frame.lua
index 9691a92..4328a90 100644
--- a/Frame.lua
+++ b/Frame.lua
@@ -81,15 +81,9 @@ local FACTION_HORDE = BFAC["Horde"]
local FACTION_ALLIANCE = BFAC["Alliance"]
local FACTION_NEUTRAL = BFAC["Neutral"]
-local CATEGORY_COLORS = private.category_colors
local BASIC_COLORS = private.basic_colors
-local SF = private.recipe_state_flags
-
local A = private.acquire_types
-local A_MAX = 9
-
-local COMMON1 = private.common_flags_word1
-------------------------------------------------------------------------------
-- Define the static popups we're going to call when people haven't scanned or
@@ -147,7 +141,6 @@ local SetTextColor = private.SetTextColor
local AcquireTable = private.AcquireTable
local ReleaseTable = private.ReleaseTable
-local ListFrame
local MainPanel
local FilterValueMap -- Assigned in InitializeFrame()
@@ -307,486 +300,6 @@ do
end -- do
-------------------------------------------------------------------------------
--- Tooltip functions and data.
--------------------------------------------------------------------------------
-local spell_tip = CreateFrame("GameTooltip", "arlSpellTooltip", UIParent, "GameTooltipTemplate")
-local acquire_tip
-
--- Font Objects needed for acquire_tip
-local narrowFont
-local normalFont
-
-local ListItem_ShowTooltip
-do
- -- Fallback in case the user doesn't have LSM-3.0 installed
- if not LibStub:GetLibrary("LibSharedMedia-3.0", true) then
-
- local locale = GetLocale()
- -- Fix for font issues on koKR
- if locale == "koKR" then
- narrowFont = "Fonts\\2002.TTF"
- normalFont = "Fonts\\2002.TTF"
- else
- narrowFont = "Fonts\\ARIALN.TTF"
- normalFont = "Fonts\\FRIZQT__.TTF"
- end
- else
- -- Register LSM 3.0
- local LSM3 = LibStub("LibSharedMedia-3.0")
-
- narrowFont = LSM3:Fetch(LSM3.MediaType.FONT, "Arial Narrow")
- normalFont = LSM3:Fetch(LSM3.MediaType.FONT, "Friz Quadrata TT")
- end
- local narrowFontObj = CreateFont(MODNAME.."narrowFontObj")
- local normalFontObj = CreateFont(MODNAME.."normalFontObj")
-
- -- I want to do a bit more comprehensive tooltip processing. Things like changing font sizes,
- -- adding padding to the left hand side, and using better color handling. So... this function
- -- will do that for me.
- local function ttAdd(
- leftPad, -- number of times to pad two spaces on left side
- textSize, -- add to or subtract from addon.db.profile.tooltip.acquire_fontsize to get fontsize
- narrow, -- if 1, use ARIALN instead of FRITZQ
- str1, -- left-hand string
- hexcolor1, -- hex color code for left-hand side
- str2, -- if present, this is the right-hand string
- hexcolor2) -- if present, hex color code for right-hand side
-
- -- are we changing fontsize or narrow?
- local fontSize
-
- if narrow or textSize ~= 0 then
- local font = narrow and narrowFont or normalFont
- local fontObj = narrow and narrowFontObj or normalFontObj
-
- fontSize = addon.db.profile.tooltip.acquire_fontsize + textSize
-
- fontObj:SetFont(font, fontSize)
- acquire_tip:SetFont(fontObj)
- end
-
- -- Add in our left hand padding
- local loopPad = leftPad
- local leftStr = str1
-
- while loopPad > 0 do
- leftStr = " " .. leftStr
- loopPad = loopPad - 1
- end
- -- Set maximum width to match fontSize to maintain uniform tooltip size. -Torhal
- local width = math.ceil(fontSize * 37.5)
- local line = acquire_tip:AddLine()
-
- if str2 then
- width = width / 2
-
- acquire_tip:SetCell(line, 1, "|cff"..hexcolor1..leftStr.."|r", "LEFT", nil, nil, 0, 0, width, width)
- acquire_tip:SetCell(line, 2, "|cff"..hexcolor2..str2.."|r", "RIGHT", nil, nil, 0, 0, width, width)
- else
- acquire_tip:SetCell(line, 1, "|cff"..hexcolor1..leftStr.."|r", nil, "LEFT", 2, nil, 0, 0, width, width)
- end
- end
-
- local function SetSpellTooltip(owner, loc, link)
- spell_tip:SetOwner(owner, "ANCHOR_NONE")
- spell_tip:ClearAllPoints()
-
- if loc == "Top" then
- spell_tip:SetPoint("BOTTOMLEFT", owner, "TOPLEFT")
- elseif loc == "Bottom" then
- spell_tip:SetPoint("TOPLEFT", owner, "BOTTOMLEFT")
- elseif loc == "Left" then
- spell_tip:SetPoint("TOPRIGHT", owner, "TOPLEFT")
- elseif loc == "Right" then
- spell_tip:SetPoint("TOPLEFT", owner, "TOPRIGHT")
- end
-
- -- Add TipTac Support
- if _G.TipTac and _G.TipTac.AddModifiedTip and not spell_tip.tiptac then
- _G.TipTac:AddModifiedTip(spell_tip)
- spell_tip.tiptac = true
- end
-
- -- Set the spell tooltip's scale, and copy its other values from GameTooltip so AddOns which modify it will work.
- spell_tip:SetBackdrop(GameTooltip:GetBackdrop())
- spell_tip:SetBackdropColor(GameTooltip:GetBackdropColor())
- spell_tip:SetBackdropBorderColor(GameTooltip:GetBackdropBorderColor())
- spell_tip:SetScale(addon.db.profile.tooltip.scale)
- spell_tip:SetClampedToScreen(true)
- spell_tip:SetHyperlink(link)
- spell_tip:Show()
- end
-
- local function GetTipFactionInfo(comp_faction)
- local display_tip
- local color
-
- if comp_faction == FACTION_NEUTRAL then
- color = private.reputation_colors["neutral"]
- display_tip = true
- elseif comp_faction == BFAC[Player.faction] then
- color = private.reputation_colors["exalted"]
- display_tip = true
- else
- color = private.reputation_colors["hated"]
- display_tip = addon.db.profile.filters.general.faction
- end
- return display_tip, color
- end
-
- -------------------------------------------------------------------------------
- -- Functions for adding individual acquire type data to the tooltip.
- -------------------------------------------------------------------------------
- local function Tooltip_AddTrainer(id_num, location, addline_func)
- local trainer = private.trainer_list[id_num]
-
- if location and trainer.location ~= location then
- return
- end
- local display_tip, name_color = GetTipFactionInfo(trainer.faction)
-
- if display_tip then
- local coord_text = ""
-
- if trainer.coord_x ~= 0 and trainer.coord_y ~= 0 then
- coord_text = "(" .. trainer.coord_x .. ", " .. trainer.coord_y .. ")"
- end
- addline_func(0, -2, false, L["Trainer"], CATEGORY_COLORS["trainer"], trainer.name, name_color)
- addline_func(1, -2, true, trainer.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
- end
- end
-
- local function Tooltip_AddVendor(recipe_id, id_num, location, addline_func)
- local vendor = private.vendor_list[id_num]
-
- if location and vendor.location ~= location then
- return
- end
- local type_color = CATEGORY_COLORS["vendor"]
- local display_tip, name_color = GetTipFactionInfo(vendor.faction)
-
- if display_tip then
- local coord_text = ""
-
- if vendor.coord_x ~= 0 and vendor.coord_y ~= 0 then
- coord_text = "(" .. vendor.coord_x .. ", " .. vendor.coord_y .. ")"
- end
- addline_func(0, -1, false, L["Vendor"], type_color, vendor.name, name_color)
- addline_func(1, -2, true, vendor.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
-
- local quantity = vendor.item_list[recipe_id]
-
- if type(quantity) == "number" then
- addline_func(2, -2, true, L["LIMITED_SUPPLY"], type_color, string.format("(%d)", quantity), BASIC_COLORS["white"])
- end
- end
- end
-
- local function Tooltip_AddMobDrop(id_num, location, addline_func)
- local mob = private.mob_list[id_num]
-
- if location and mob.location ~= location then
- return
- end
- local coord_text = ""
-
- if mob.coord_x ~= 0 and mob.coord_y ~= 0 then
- coord_text = "(" .. mob.coord_x .. ", " .. mob.coord_y .. ")"
- end
- addline_func(0, -1, false, L["Mob Drop"], CATEGORY_COLORS["mobdrop"], mob.name, private.reputation_colors["hostile"])
- addline_func(1, -2, true, mob.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
- end
-
- local function Tooltip_AddQuest(id_num, location, addline_func)
- local quest = private.quest_list[id_num]
-
- if location and quest.location ~= location then
- return
- end
- local type_color = CATEGORY_COLORS["quest"]
- local display_tip, name_color = GetTipFactionInfo(quest.faction)
-
- if display_tip then
- local coord_text = ""
-
- if quest.coord_x ~= 0 and quest.coord_y ~= 0 then
- coord_text = "(" .. quest.coord_x .. ", " .. quest.coord_y .. ")"
- end
- addline_func(0, -1, false, L["Quest"], type_color, private.quest_names[id_num], name_color)
- addline_func(1, -2, true, quest.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
- end
- end
-
- local function Tooltip_AddRepVendor(id_num, location, rep_id, rep_level, vendor_id, addline_func)
- local rep_vendor = private.vendor_list[vendor_id]
-
- if location and rep_vendor.location ~= location then
- return
- end
- local display_tip, name_color = GetTipFactionInfo(rep_vendor.faction)
-
- if display_tip then
- local rep_color = private.reputation_colors
- local rep_str = ""
- local type_color
-
- if rep_level == 0 then
- rep_str = FACTION_NEUTRAL
- type_color = rep_color["neutral"]
- elseif rep_level == 1 then
- rep_str = BFAC["Friendly"]
- type_color = rep_color["friendly"]
- elseif rep_level == 2 then
- rep_str = BFAC["Honored"]
- type_color = rep_color["honored"]
- elseif rep_level == 3 then
- rep_str = BFAC["Revered"]
- type_color = rep_color["revered"]
- else
- rep_str = BFAC["Exalted"]
- type_color = rep_color["exalted"]
- end
- addline_func(0, -1, false, _G.REPUTATION, CATEGORY_COLORS["reputation"], private.reputation_list[id_num].name, CATEGORY_COLORS["repname"])
- addline_func(1, -2, false, rep_str, type_color, rep_vendor.name, name_color)
-
- local coord_text = ""
-
- if rep_vendor.coord_x ~= 0 and rep_vendor.coord_y ~= 0 then
- coord_text = "(" .. rep_vendor.coord_x .. ", " .. rep_vendor.coord_y .. ")"
- end
- addline_func(2, -2, true, rep_vendor.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
- end
- end
-
- local function Tooltip_AddWorldDrop(recipe_id, id_num, location, addline_func)
- local drop_location = type(id_num) == "string" and BZ[id_num] or nil
-
- if location and drop_location ~= location then
- return
- end
- local item_id = private.spell_to_recipe_map[recipe_id]
- local _, item_level
-
- if item_id then
- _, _, _, item_level = GetItemInfo(item_id)
- end
- local _, _, _, quality_color = GetItemQualityColor(private.recipe_list[recipe_id].quality)
- local type_color = string.gsub(quality_color, "|cff", "")
-
- if type(id_num) == "string" then
- local location_text = item_level and string.format("%s (%d - %d)", drop_location, item_level - 5, item_level + 5) or drop_location
-
- addline_func(0, -1, false, L["World Drop"], type_color, location_text, CATEGORY_COLORS["location"])
- else
- local location_text = item_level and string.format("%s (%d - %d)", _G.UNKNOWN, item_level - 5, item_level + 5) or _G.UNKNOWN
-
- addline_func(0, -1, false, L["World Drop"], type_color, location_text, CATEGORY_COLORS["location"])
- end
- end
-
- -------------------------------------------------------------------------------
- -- Public API function for displaying a recipe's acquire data.
- -- * The addline_func paramater must be a function which accepts the same
- -- * arguments as ARL's ttAdd function.
- -------------------------------------------------------------------------------
- function addon:DisplayAcquireData(recipe_id, acquire_id, location, addline_func)
- local recipe = private.recipe_list[recipe_id]
-
- if not recipe then
- return
- end
-
- for acquire_type, acquire_data in pairs(recipe.acquire_data) do
- local can_display = (not acquire_id or acquire_type == acquire_id)
-
- if can_display then
- for id_num, info in pairs(acquire_data) do
- if acquire_type == A.TRAINER then
- Tooltip_AddTrainer(id_num, location, addline_func)
- elseif acquire_type == A.VENDOR then
- Tooltip_AddVendor(recipe_id, id_num, location, addline_func)
- elseif acquire_type == A.MOB_DROP then
- Tooltip_AddMobDrop(id_num, location, addline_func)
- elseif acquire_type == A.QUEST then
- Tooltip_AddQuest(id_num, location, addline_func)
- elseif acquire_type == A.SEASONAL then
- color_1 = CATEGORY_COLORS["seasonal"]
- addline_func(0, -1, 0, private.acquire_names[A.SEASONAL], color_1, private.seasonal_list[id_num].name, color_1)
- elseif acquire_type == A.REPUTATION then
- for rep_level, level_info in pairs(info) do
- for vendor_id in pairs(level_info) do
- Tooltip_AddRepVendor(id_num, location, rep_id, rep_level, vendor_id, addline_func)
- end
- end
- elseif acquire_type == A.WORLD_DROP then
- Tooltip_AddWorldDrop(recipe_id, id_num, location, addline_func)
- elseif acquire_type == A.CUSTOM then
- addline_func(0, -1, false, private.custom_list[id_num].name, CATEGORY_COLORS["custom"])
- --@alpha@
- elseif can_display then
- -- Unhandled
- addline_func(0, -1, 0, L["Unhandled Recipe"], BASIC_COLORS["normal"])
- --@end-alpha@
- end
- end -- for id_num
- end -- if can_display
- end -- for acquire_type
- end
-
- -------------------------------------------------------------------------------
- -- Main tooltip-generating function.
- -------------------------------------------------------------------------------
- local BINDING_FLAGS = {
- [COMMON1.IBOE] = L["BOEFilter"],
- [COMMON1.IBOP] = L["BOPFilter"],
- [COMMON1.IBOA] = L["BOAFilter"],
- [COMMON1.RBOE] = L["RecipeBOEFilter"],
- [COMMON1.RBOP] = L["RecipeBOPFilter"],
- [COMMON1.RBOA] = L["RecipeBOAFilter"]
- }
-
- function ListItem_ShowTooltip(owner, list_entry)
- if not list_entry then
- return
- end
- local recipe_id = list_entry.recipe_id
- local recipe = private.recipe_list[recipe_id]
-
- if not recipe then
- return
- end
- local spell_tip_anchor = addon.db.profile.spelltooltiplocation
- local acquire_tip_anchor = addon.db.profile.acquiretooltiplocation
- local spell_link = GetSpellLink(recipe.spell_id)
- local MainPanel = addon.Frame
-
- if acquire_tip_anchor == _G.OFF then
- QTip:Release(acquire_tip)
-
- -- If we have the spell link tooltip, anchor it to MainPanel instead so it shows
- if spell_tip_anchor ~= _G.OFF and spell_link then
- SetSpellTooltip(MainPanel, spell_tip_anchor, spell_link)
- else
- spell_tip:Hide()
- end
- return
- end
- acquire_tip = QTip:Acquire(MODNAME.." Tooltip", 2, "LEFT", "LEFT")
- acquire_tip:ClearAllPoints()
-
- if acquire_tip_anchor == "Right" then
- acquire_tip:SetPoint("TOPLEFT", MainPanel, "TOPRIGHT", MainPanel.is_expanded and -90 or -35, 0)
- elseif acquire_tip_anchor == "Left" then
- acquire_tip:SetPoint("TOPRIGHT", MainPanel, "TOPLEFT")
- elseif acquire_tip_anchor == "Top" then
- acquire_tip:SetPoint("BOTTOMLEFT", MainPanel, "TOPLEFT")
- elseif acquire_tip_anchor == "Bottom" then
- acquire_tip:SetPoint("TOPLEFT", MainPanel, "BOTTOMLEFT", 0, 55)
- elseif acquire_tip_anchor == "Mouse" then
- local x, y = GetCursorPosition()
- local uiscale = UIParent:GetEffectiveScale()
-
- acquire_tip:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x / uiscale, y / uiscale)
- end
- acquire_tip:SetClampedToScreen(true)
-
- if _G.TipTac and _G.TipTac.AddModifiedTip then
- -- Pass true as second parameter because hooking OnHide causes C stack overflows -Torhal
- _G.TipTac:AddModifiedTip(acquire_tip, true)
- end
- local _, _, _, quality_color = GetItemQualityColor(recipe.quality)
-
- acquire_tip:Clear()
- acquire_tip:SetScale(addon.db.profile.tooltip.scale)
- acquire_tip:AddHeader()
- acquire_tip:SetCell(1, 1, quality_color..recipe.name, "CENTER", 2)
-
- -- check if the recipe is excluded
- if addon.db.profile.exclusionlist[recipe_id] then
- ttAdd(0, -1, true, L["RECIPE_EXCLUDED"], "ff0000")
- end
-
- -- Add in skill level requirement, colored correctly
- local color_1 = BASIC_COLORS["normal"]
- local color_2
-
- local skill_level = Player["ProfessionLevel"]
- local recipe_level = recipe.skill_level
- local optimal_level = recipe.optimal_level
- local medium_level = recipe.medium_level
- local easy_level = recipe.easy_level
- local trivial_level = recipe.trivial_level
- local difficulty = private.difficulty_colors
-
- if recipe_level > skill_level then
- color_2 = difficulty["impossible"]
- elseif skill_level >= trivial_level then
- color_2 = difficulty["trivial"]
- elseif skill_level >= easy_level then
- color_2 = difficulty["easy"]
- elseif skill_level >= medium_level then
- color_2 = difficulty["medium"]
- elseif skill_level >= optimal_level then
- color_2 = difficulty["optimal"]
- else
- color_2 = difficulty["trivial"]
- end
- ttAdd(0, -1, false, string.format("%s:", _G.SKILL_LEVEL), color_1, recipe.skill_level, color_2)
-
- -- Binding info
- acquire_tip:AddSeparator()
- color_1 = BASIC_COLORS["normal"]
-
- for flag, label in pairs(BINDING_FLAGS) do
- if bit.band(recipe.flags.common1, flag) == flag then
- ttAdd(0, -1, true, label, color_1)
- end
- end
- acquire_tip:AddSeparator()
-
- if recipe.specialty then
- local spec = recipe.specialty
- local spec_name = GetSpellInfo(spec)
- local known = (spec == Player["Specialty"])
-
- ttAdd(0, -1, false, string.format(_G.ITEM_REQ_SKILL, spec_name), known and BASIC_COLORS["white"] or difficulty["impossible"])
- acquire_tip:AddSeparator()
- end
-
- ttAdd(0, -1, false, L["Obtained From"] .. " : ", BASIC_COLORS["normal"])
-
- local acquire_id = list_entry.acquire_id
- local location = list_entry.location_id
-
- addon:DisplayAcquireData(recipe_id, acquire_id, location, ttAdd)
-
- if not addon.db.profile.hide_tooltip_hint then
- -- Give the tooltip hint a unique color.
- color_1 = "c9c781"
-
- acquire_tip:AddSeparator()
- acquire_tip:AddSeparator()
-
- ttAdd(0, -1, 0, L["ALT_CLICK"], color_1)
- ttAdd(0, -1, 0, L["CTRL_CLICK"], color_1)
- ttAdd(0, -1, 0, L["SHIFT_CLICK"], color_1)
-
- if acquire_id ~= A.WORLD_DROP and acquire_id ~= A.CUSTOM and (_G.TomTom or _G.Cartographer_Waypoints) and (addon.db.profile.worldmap or addon.db.profile.minimap) then
- ttAdd(0, -1, 0, L["CTRL_SHIFT_CLICK"], color_1)
- end
- end
- acquire_tip:Show()
-
- -- If we have the spell link tooltip, link it to the acquire tooltip.
- if spell_tip_anchor ~= _G.OFF and spell_link then
- SetSpellTooltip(acquire_tip, spell_tip_anchor, spell_link)
- else
- spell_tip:Hide()
- end
- end
-end -- do
-
--------------------------------------------------------------------------------
-- Create the MainPanel and set its values
-------------------------------------------------------------------------------
local MainPanel
@@ -1163,7 +676,7 @@ MainPanel.search_editbox = SearchBox
SearchBox:SetText(_G.SEARCH)
SearchBox:SetHistoryLines(10)
--- Resets the SearchBox text and the state of all ListFrame and recipe_list entries.
+-- Resets the SearchBox text and the state of all MainPanel.list_frame and recipe_list entries.
function SearchBox:Reset()
local recipe_list = private.recipe_list
@@ -1174,7 +687,7 @@ function SearchBox:Reset()
self:SetText(_G.SEARCH)
self:ClearFocus()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end
-- If there is text in the search box, return the recipe's RELEVANT state.
@@ -1206,7 +719,7 @@ SearchBox:SetScript("OnEnterPressed",
self:HighlightText()
self:AddHistoryLine(searchtext)
SearchRecipes(searchtext)
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
SearchBox:SetScript("OnEditFocusGained",
@@ -1252,7 +765,7 @@ do
last_update = 0
SearchRecipes(SearchBox:GetText())
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
self:Hide()
end
end)
@@ -1300,7 +813,7 @@ ExpandButtonFrame.middle:SetTexture("Interface\\QuestFrame\\UI-QuestLogSortTab-M
local ExpandButton = GenericCreateButton(nil, MainPanel, 16, 16, "GameFontNormalSmall", _G.ALL, "LEFT", L["EXPANDALL_DESC"], 2)
-MainPanel.expand_all_button = ExpandButton
+MainPanel.expand_button = ExpandButton
ExpandButton:SetPoint("LEFT", ExpandButtonFrame.left, "RIGHT", -3, -3)
@@ -1324,10 +837,10 @@ ExpandButton:SetScript("OnClick",
table.wipe(current_tab[prof_name.." expanded"])
end
- -- ListFrame:Update() must be called before the button can be expanded or contracted, since
+ -- MainPanel.list_frame:Update() must be called before the button can be expanded or contracted, since
-- the button is contracted from there.
-- If expand_mode is nil, that means expand nothing.
- ListFrame:Update(expand_mode, false)
+ MainPanel.list_frame:Update(expand_mode, false)
if expanded then
self:Contract(current_tab)
@@ -1372,7 +885,7 @@ SkillToggle.text:SetPoint("LEFT", SkillToggle, "RIGHT", 0, 0)
SkillToggle:SetScript("OnClick",
function(self, button, down)
addon.db.profile.skill_view = not addon.db.profile.skill_view
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
SkillToggle:SetScript("OnShow",
@@ -1403,7 +916,7 @@ ExcludeToggle.text:SetPoint("LEFT", ExcludeToggle, "RIGHT", 0, 0)
ExcludeToggle:SetScript("OnClick",
function(self, button, down)
addon.db.profile.ignoreexclusionlist = not addon.db.profile.ignoreexclusionlist
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
ExcludeToggle:SetScript("OnShow",
@@ -1561,7 +1074,7 @@ do
if MainPanel:IsVisible() then
MainPanel:UpdateTitle()
UpdateFilterMarks()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end
end
MainPanel.filter_reset:SetScript("OnClick", ResetFilters)
@@ -1578,7 +1091,7 @@ do
FilterValueMap[script_val].svroot[script_val] = FilterValueMap[script_val].cb:GetChecked() and true or false
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end
local function CreateCheckButton(parent, ttText, scriptVal, row, col)
@@ -1612,30 +1125,6 @@ do
end -- do
-------------------------------------------------------------------------------
--- Create the ListFrame and set its scripts.
--------------------------------------------------------------------------------
-ListFrame = CreateFrame("Frame", "ARL_MainPanelScrollFrame", MainPanel)
-
-MainPanel.list_frame = ListFrame
-
-ListFrame:SetHeight(335)
-ListFrame:SetWidth(295)
-ListFrame:SetPoint("TOPLEFT", MainPanel, "TOPLEFT", 22, -75)
-ListFrame:SetBackdrop({
- bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
- tile = true,
- tileSize = 16,
- })
-ListFrame:SetBackdropColor(1, 1, 1)
-ListFrame:EnableMouse(true)
-ListFrame:EnableMouseWheel(true)
-
-ListFrame.entries = {}
-ListFrame.button_containers = {}
-ListFrame.state_buttons = {}
-ListFrame.entry_buttons = {}
-
--------------------------------------------------------------------------------
-- Sort-mode toggle button.
-------------------------------------------------------------------------------
local SortToggle = GenericCreateButton(nil, MainPanel, 24, 24, nil, nil, nil, L["SORTING_DESC"], 2)
@@ -1651,7 +1140,7 @@ SortToggle:SetScript("OnClick",
addon.db.profile.sorting = (sort_type == "Ascending" and "Descending" or "Ascending")
self:SetTextures()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
SortToggle:SetHighlightTexture([[Interface\CHATFRAME\UI-ChatIcon-BlinkHilight]])
@@ -1671,1026 +1160,6 @@ function SortToggle:SetTextures()
end
-------------------------------------------------------------------------------
--- Create ListFrame.scroll_bar, and set its scripts.
--------------------------------------------------------------------------------
-local ScrollBar = CreateFrame("Slider", nil, ListFrame)
-
-ScrollBar:SetPoint("TOPLEFT", ListFrame, "TOPRIGHT", 5, -11)
-ScrollBar:SetPoint("BOTTOMLEFT", ListFrame, "BOTTOMRIGHT", 5, 12)
-ScrollBar:SetWidth(24)
-
-ScrollBar:EnableMouseWheel(true)
-ScrollBar:SetOrientation("VERTICAL")
-
-ScrollBar:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
-ScrollBar:SetMinMaxValues(0, 1)
-ScrollBar:SetValueStep(1)
-
-ListFrame.scroll_bar = ScrollBar
-
--------------------------------------------------------------------------------
--- Create ListFrame.button_up, then set its scripts and textures.
--- Parented to ScrollBar so it hides simultaneously.
--------------------------------------------------------------------------------
-local ScrollUpButton = CreateFrame("Button", nil, ScrollBar, "UIPanelScrollUpButtonTemplate")
-
-ScrollUpButton:SetHeight(16)
-ScrollUpButton:SetWidth(18)
-ScrollUpButton:SetPoint("BOTTOM", ScrollBar, "TOP", 0, -4)
-
--------------------------------------------------------------------------------
--- Create ListFrame.button_down, then set its scripts and textures.
--- Parented to ScrollBar so it hides simultaneously.
--------------------------------------------------------------------------------
-local ScrollDownButton = CreateFrame("Button", nil, ScrollBar,"UIPanelScrollDownButtonTemplate")
-
-ScrollDownButton:SetHeight(16)
-ScrollDownButton:SetWidth(18)
-ScrollDownButton:SetPoint("TOP", ScrollBar, "BOTTOM", 0, 4)
-
-do
- -- Number of visible lines in the scrollframe.
- local NUM_RECIPE_LINES = 25
- local SCROLL_DEPTH = 5
-
- local function ScrollBar_Scroll(delta)
- if not ScrollBar:IsShown() then
- return
- end
- local cur_val = ScrollBar:GetValue()
- local min_val, max_val = ScrollBar:GetMinMaxValues()
-
- if delta < 0 and cur_val < max_val then
- cur_val = math.min(max_val, cur_val + SCROLL_DEPTH)
- ScrollBar:SetValue(cur_val)
- elseif delta > 0 and cur_val > min_val then
- cur_val = math.max(min_val, cur_val - SCROLL_DEPTH)
- ScrollBar:SetValue(cur_val)
- end
- end
-
- ScrollUpButton:SetScript("OnClick",
- function(self, button, down)
- if _G.IsAltKeyDown() then
- local min_val = ScrollBar:GetMinMaxValues()
- ScrollBar:SetValue(min_val)
- else
- ScrollBar_Scroll(1)
- end
- end)
-
- ScrollDownButton:SetScript("OnClick",
- function(self, button, down)
- if _G.IsAltKeyDown() then
- local _, max_val = ScrollBar:GetMinMaxValues()
- ScrollBar:SetValue(max_val)
- else
- ScrollBar_Scroll(-1)
- end
- end)
-
- ScrollBar:SetScript("OnMouseWheel",
- function(self, delta)
- ScrollBar_Scroll(delta)
- end)
-
- ListFrame:SetScript("OnMouseWheel",
- function(self, delta)
- ScrollBar_Scroll(delta)
- end)
-
- -- This can be called either from ListFrame's OnMouseWheel script, manually
- -- sliding the thumb, or from clicking the up/down buttons.
- ScrollBar:SetScript("OnValueChanged",
- function(self, value)
- local min_val, max_val = self:GetMinMaxValues()
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
- local member = "profession_"..MainPanel.profession.."_scroll_value"
-
- current_tab[member] = value
-
- if value == min_val then
- ScrollUpButton:Disable()
- ScrollDownButton:Enable()
- elseif value == max_val then
- ScrollUpButton:Enable()
- ScrollDownButton:Disable()
- else
- ScrollUpButton:Enable()
- ScrollDownButton:Enable()
- end
- ListFrame:Update(nil, true)
- end)
-
- local function Button_OnEnter(self)
- ListItem_ShowTooltip(self, ListFrame.entries[self.string_index])
- end
-
- local function Button_OnLeave()
- QTip:Release(acquire_tip)
- spell_tip:Hide()
- end
-
- local function Bar_OnEnter(self)
- ListItem_ShowTooltip(self, ListFrame.entries[self.string_index])
- end
-
- local function Bar_OnLeave()
- QTip:Release(acquire_tip)
- spell_tip:Hide()
- end
-
- local function ListItem_OnClick(self, button, down)
- local clickedIndex = self.string_index
-
- -- Don't do anything if they've clicked on an empty button
- if not clickedIndex or clickedIndex == 0 then
- return
- end
- local clicked_line = ListFrame.entries[clickedIndex]
- local traverseIndex = 0
-
- if not clicked_line then
- return
- end
- -- First, check if this is a "modified" click, and react appropriately
- if clicked_line.recipe_id and _G.IsModifierKeyDown() then
- if _G.IsControlKeyDown() and _G.IsShiftKeyDown() then
- addon:AddWaypoint(clicked_line.recipe_id, clicked_line.acquire_id, clicked_line.location_id, clicked_line.npc_id)
- elseif _G.IsShiftKeyDown() then
- local itemID = private.recipe_list[clicked_line.recipe_id].item_id
-
- if itemID then
- local _, itemLink = _G.GetItemInfo(itemID)
-
- if itemLink then
- local edit_box = _G.ChatEdit_ChooseBoxForSend()
-
- _G.ChatEdit_ActivateChat(edit_box)
- edit_box:Insert(itemLink)
- else
- addon:Print(L["NoItemLink"])
- end
- else
- addon:Print(L["NoItemLink"])
- end
- elseif _G.IsControlKeyDown() then
- local edit_box = _G.ChatEdit_ChooseBoxForSend()
-
- _G.ChatEdit_ActivateChat(edit_box)
- edit_box:Insert(GetSpellLink(private.recipe_list[clicked_line.recipe_id].spell_id))
- elseif _G.IsAltKeyDown() then
- local exclusion_list = addon.db.profile.exclusionlist
- local recipe_id = clicked_line.recipe_id
-
- exclusion_list[recipe_id] = (not exclusion_list[recipe_id] and true or nil)
- ListFrame:Update(nil, false)
- end
- elseif clicked_line.type == "header" or clicked_line.type == "subheader" then
- -- three possibilities here (all with no modifiers)
- -- 1) We clicked on the recipe button on a closed recipe
- -- 2) We clicked on the recipe button of an open recipe
- -- 3) we clicked on the expanded text of an open recipe
- if clicked_line.is_expanded then
- traverseIndex = clickedIndex + 1
-
- local check_type = clicked_line.type
- local entry = ListFrame.entries[traverseIndex]
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
-
- -- get rid of our expanded lines
- while entry and entry.type ~= check_type do
- -- Headers are never removed.
- if entry.type == "header" then
- break
- end
- current_tab:ModifyEntry(entry, false)
- ReleaseTable(table.remove(ListFrame.entries, traverseIndex))
- entry = ListFrame.entries[traverseIndex]
-
- if not entry then
- break
- end
- end
- current_tab:ModifyEntry(clicked_line, false)
- clicked_line.is_expanded = false
- else
- ListFrame:ExpandEntry(clickedIndex)
- clicked_line.is_expanded = true
- end
- else
- -- clicked_line is an expanded entry - find the index for its parent, and remove all of the parent's child entries.
- local parent = clicked_line.parent
-
- if parent then
- local parent_index
- local entries = ListFrame.entries
-
- for index = 1, #entries do
- if entries[index] == parent then
- parent_index = index
- break
- end
- end
-
- if not parent_index then
- addon:Debug("clicked_line (%s): parent wasn't found in ListFrame.entries", clicked_line.text)
- return
- end
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
-
- parent.is_expanded = false
- current_tab:ModifyEntry(parent, false)
-
- local child_index = parent_index + 1
-
- while entries[child_index] and entries[child_index].parent == parent do
- ReleaseTable(table.remove(entries, child_index))
- end
- else
- addon:Debug("Error: clicked_line has no parent.")
- end
- end
- QTip:Release(acquire_tip)
- spell_tip:Hide()
-
- ListFrame:Update(nil, true)
- end
- local LISTFRAME_WIDTH = ListFrame:GetWidth()
-
- -------------------------------------------------------------------------------
- -- Create the state/entry buttons and the container frames which hold them.
- -------------------------------------------------------------------------------
- for i = 1, NUM_RECIPE_LINES do
- local cur_container = CreateFrame("Frame", nil, ListFrame)
-
- cur_container:SetHeight(16)
- cur_container:SetWidth(LISTFRAME_WIDTH)
-
- local cur_state = GenericCreateButton(nil, ListFrame, 16, 16, nil, nil, nil, nil, 2)
- local cur_entry = GenericCreateButton(nil, ListFrame, 16, LISTFRAME_WIDTH, "GameFontNormalSmall", "Blort", "LEFT", nil, 0)
-
- if i == 1 then
- cur_container:SetPoint("TOPLEFT", ListFrame, "TOPLEFT", 0, 0)
- cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
- cur_entry:SetPoint("TOPLEFT", cur_state, "TOPRIGHT", -3, 0)
- else
- local prev_container = ListFrame.button_containers[i - 1]
-
- cur_container:SetPoint("TOPLEFT", prev_container, "BOTTOMLEFT", 0, 3)
- cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
- cur_entry:SetPoint("TOPLEFT", cur_state, "TOPRIGHT", -3, 0)
- end
- cur_state.container = cur_container
-
- cur_state:SetScript("OnClick", ListItem_OnClick)
- cur_entry:SetScript("OnClick", ListItem_OnClick)
-
- ListFrame.button_containers[i] = cur_container
- ListFrame.state_buttons[i] = cur_state
- ListFrame.entry_buttons[i] = cur_entry
- end
-
- function ListFrame:InsertEntry(entry, parent_entry, entry_index, entry_type, entry_expanded, expand_mode)
- entry.type = entry_type
-
- if parent_entry then
- if parent_entry ~= entry then
- entry.parent = parent_entry
-
- local recipe_id = parent_entry.recipe_id
- local acquire_id = parent_entry.acquire_id
- local location_id = parent_entry.location_id
- local npc_id = parent_entry.npc_id
-
- if recipe_id then
- entry.recipe_id = recipe_id
- end
-
- if acquire_id then
- entry.acquire_id = acquire_id
- end
-
- if location_id then
- entry.location_id = location_id
- end
-
- if npc_id then
- entry.npc_id = npc_id
- end
- else
- addon:Debug("Attempting to parent an entry to itself.")
- end
- elseif entry.type ~= "header" then
- addon:Debug("Non-header entry without a parent: %s - %s", entry.type, entry.text)
- end
- local insert_index = entry_index
-
- -- If we have acquire information for this entry, push the data table into the list
- -- and start processing the acquires.
- if expand_mode then
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
-
- entry.is_expanded = true
- table.insert(self.entries, insert_index, entry)
-
- current_tab:ModifyEntry(entry, entry_expanded)
-
- if entry_type == "header" or entry_type == "subheader" then
- insert_index = self:ExpandEntry(insert_index, expand_mode)
- else
- insert_index = insert_index + 1
- end
- else
- entry.is_expanded = entry_expanded
- table.insert(self.entries, insert_index, entry)
-
- insert_index = insert_index + 1
- end
- return insert_index
- end
-
- function ListFrame:Initialize(expand_mode)
- for i = 1, #self.entries do
- ReleaseTable(self.entries[i])
- end
- table.wipe(self.entries)
-
- addon:UpdateFilters(MainPanel.is_linked)
-
- -------------------------------------------------------------------------------
- -- Mark all exclusions in the recipe database to not be displayed, and update
- -- the player's known and unknown counts.
- -------------------------------------------------------------------------------
- local exclusion_list = addon.db.profile.exclusionlist
- local ignored = not addon.db.profile.ignoreexclusionlist
- local recipe_list = private.recipe_list
- local current_prof = ORDERED_PROFESSIONS[MainPanel.profession]
- local known_count = 0
- local unknown_count = 0
-
- for spell_id in pairs(exclusion_list) do
- local recipe = recipe_list[spell_id]
-
- if recipe then
- if recipe:HasState("KNOWN") and recipe.profession == current_prof then
- known_count = known_count + 1
- elseif recipe_profession == current_prof then
- unknown_count = unknown_count + 1
- end
- end
- end
- Player.excluded_recipes_known = known_count
- Player.excluded_recipes_unknown = unknown_count
-
- -------------------------------------------------------------------------------
- -- Initialize the expand button and entries for the current tab.
- -------------------------------------------------------------------------------
- local current_tab = MainPanel.tabs[addon.db.profile.current_tab]
- local expanded_button = current_tab["expand_button_"..MainPanel.profession]
-
- if expanded_button then
- ExpandButton:Expand(current_tab)
- else
- ExpandButton:Contract(current_tab)
- end
- local recipe_count = current_tab:Initialize(expand_mode)
-
- -------------------------------------------------------------------------------
- -- Update the progress bar display.
- -------------------------------------------------------------------------------
- local profile = addon.db.profile
- local max_value = profile.includefiltered and Player.recipes_total or Player.recipes_total_filtered
- local cur_value = profile.includefiltered and Player.recipes_known or Player.recipes_known_filtered
-
- if not profile.includeexcluded and not profile.ignoreexclusionlist then
- max_value = max_value - Player.excluded_recipes_known
- end
- local progress_bar = MainPanel.progress_bar
-
- progress_bar:SetMinMaxValues(0, max_value)
- progress_bar:SetValue(cur_value)
-
- local percentage = cur_value / max_value * 100
-
- if (floor(percentage) < 101) and cur_value >= 0 and max_value >= 0 then
- local results = string.format(_G.SINGLE_PAGE_RESULTS_TEMPLATE, recipe_count)
- progress_bar.text:SetFormattedText("%d/%d - %1.2f%% (%s)", cur_value, max_value, percentage, results)
- else
- progress_bar.text:SetFormattedText("%s", L["NOT_YET_SCANNED"])
- end
- end
-
- -- Reset the current buttons/lines
- function ListFrame:ClearLines()
- local font_object = addon.db.profile.frameopts.small_list_font and "GameFontNormalSmall" or "GameFontNormal"
-
- for i = 1, NUM_RECIPE_LINES do
- local entry = self.entry_buttons[i]
- local state = self.state_buttons[i]
-
- entry.string_index = 0
- entry.text:SetFontObject(font_object)
-
- entry:SetText("")
- entry:SetScript("OnEnter", nil)
- entry:SetScript("OnLeave", nil)
- entry:SetWidth(LISTFRAME_WIDTH)
- entry:Disable()
-
- state.string_index = 0
-
- state:Hide()
- state:SetScript("OnEnter", nil)
- state:SetScript("OnLeave", nil)
- state:Disable()
-
- state:ClearAllPoints()
- end
- end
-
- function ListFrame:Update(expand_mode, refresh)
- if not refresh then
- self:Initialize(expand_mode)
- end
-
- local num_entries = #self.entries
-
- if num_entries == 0 then
- self:ClearLines()
-
- -- disable expand button, it's useless here and would spam the same error again
- ExpandButton:SetNormalFontObject("GameFontDisableSmall")
- ExpandButton:Disable()
- self.scroll_bar:Hide()
-
- local showpopup = false
-
- if not addon.db.profile.hidepopup then
- showpopup = true
- end
-
- -- If we haven't run this before we'll show pop-ups for the first time.
- if addon.db.profile.addonversion ~= addon.version then
- addon.db.profile.addonversion = addon.version
- showpopup = true
- end
- local editbox_text = SearchBox:GetText()
-
- if Player.recipes_total == 0 then
- if showpopup then
- _G.StaticPopup_Show("ARL_NOTSCANNED")
- end
- elseif Player.recipes_known == Player.recipes_total then
- if showpopup then
- _G.StaticPopup_Show("ARL_ALLKNOWN")
- end
- elseif (Player.recipes_total_filtered - Player.recipes_known_filtered) == 0 then
- if showpopup then
- _G.StaticPopup_Show("ARL_ALLFILTERED")
- end
- elseif Player.excluded_recipes_unknown ~= 0 then
- if showpopup then
- _G.StaticPopup_Show("ARL_ALLEXCLUDED")
- end
- elseif editbox_text ~= "" and editbox_text ~= _G.SEARCH then
- _G.StaticPopup_Show("ARL_SEARCHFILTERED")
- else
- addon:Print(L["NO_DISPLAY"])
- addon:Debug("Current tab is %s", tostring(addon.db.profile.current_tab))
- addon:Debug("recipes_total check for 0")
- addon:Debug("recipes_total: " .. Player.recipes_total)
- addon:Debug("recipes_total check for equal to recipes_total")
- addon:Debug("recipes_known: " .. Player.recipes_known)
- addon:Debug("recipes_total: " .. Player.recipes_total)
- addon:Debug("recipes_total_filtered - recipes_known_filtered = 0")
- addon:Debug("recipes_total_filtered: " .. Player.recipes_total_filtered)
- addon:Debug("recipes_known_filtered: " .. Player.recipes_known_filtered)
- addon:Debug("excluded_recipes_unknown ~= 0")
- addon:Debug("excluded_recipes_unknown: " .. Player.excluded_recipes_unknown)
- end
- return
- end
- local offset = 0
-
- addon:ClosePopups()
-
- ExpandButton:SetNormalFontObject("GameFontNormalSmall")
- ExpandButton:Enable()
-
- if num_entries <= NUM_RECIPE_LINES then
- self.scroll_bar:Hide()
- else
- local max_val = num_entries - NUM_RECIPE_LINES
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
- local scroll_value = current_tab["profession_"..MainPanel.profession.."_scroll_value"] or 0
-
- scroll_value = math.max(0, math.min(scroll_value, max_val))
- offset = scroll_value
-
- self.scroll_bar:SetMinMaxValues(0, math.max(0, max_val))
- self.scroll_bar:SetValue(scroll_value)
- self.scroll_bar:Show()
- end
- self:ClearLines()
-
- local button_index = 1
- local string_index = button_index + offset
-
- -- Populate the buttons with new values
- while button_index <= NUM_RECIPE_LINES and string_index <= num_entries do
- local cur_state = self.state_buttons[button_index]
- local cur_entry = self.entries[string_index]
-
- if cur_entry.type == "header" or cur_entry.type == "subheader" then
- cur_state:Show()
-
- if cur_entry.is_expanded then
- cur_state:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up")
- cur_state:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down")
- cur_state:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
- cur_state:SetDisabledTexture("Interface\\Buttons\\UI-MinusButton-Disabled")
- else
- cur_state:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
- cur_state:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down")
- cur_state:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
- cur_state:SetDisabledTexture("Interface\\Buttons\\UI-PlusButton-Disabled")
- end
- cur_state.string_index = string_index
- cur_state:SetScript("OnEnter", Button_OnEnter)
- cur_state:SetScript("OnLeave", Button_OnLeave)
- cur_state:Enable()
- else
- cur_state:Hide()
- cur_state:Disable()
- end
- local cur_container = cur_state.container
- local cur_button = self.entry_buttons[button_index]
-
- if cur_entry.type == "header" or cur_entry.type == "entry" then
- cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
- elseif cur_entry.type == "subheader" or cur_entry.type == "subentry" then
- cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 15, 0)
- cur_button:SetWidth(LISTFRAME_WIDTH - 15)
- end
- cur_button.string_index = string_index
- cur_button:SetText(cur_entry.text)
- cur_button:SetScript("OnEnter", Bar_OnEnter)
- cur_button:SetScript("OnLeave", Bar_OnLeave)
- cur_button:Enable()
-
- button_index = button_index + 1
- string_index = string_index + 1
- end
- button_index = 1
- string_index = button_index + offset
-
- -- This function could possibly have been called from a mouse click or by scrolling.
- -- Since, in those cases, the list entries have changed, the mouse is likely over a different entry - a tooltip should be generated for it.
- while button_index <= NUM_RECIPE_LINES and string_index <= num_entries do
- local cur_state = self.state_buttons[button_index]
- local cur_button = self.entry_buttons[button_index]
-
- if cur_state:IsMouseOver() then
- Button_OnEnter(cur_state)
- break
- elseif cur_button:IsMouseOver() then
- Bar_OnEnter(cur_button)
- break
- end
- button_index = button_index + 1
- string_index = string_index + 1
- end
- end
- -------------------------------------------------------------------------------
- -- Functions and data pertaining to individual list entries.
- -------------------------------------------------------------------------------
- local faction_strings
-
- local function CanDisplayFaction(faction)
- if addon.db.profile.filters.general.faction then
- return true
- end
- return (not faction or faction == BFAC[Player.faction] or faction == FACTION_NEUTRAL)
- end
-
- -- Padding for list entries/subentries
- local PADDING = " "
-
- -- Changes the color of "name" based on faction type.
- local function ColorNameByFaction(name, faction)
- if faction == FACTION_NEUTRAL then
- name = SetTextColor(private.reputation_colors["neutral"], name)
- elseif faction == BFAC[Player.faction] then
- name = SetTextColor(private.reputation_colors["exalted"], name)
- else
- name = SetTextColor(private.reputation_colors["hated"], name)
- end
- return name
- end
-
- local function ExpandTrainerData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local trainer = private.trainer_list[id_num]
-
- if not CanDisplayFaction(trainer.faction) then
- return entry_index
- end
-
- local name = ColorNameByFaction(trainer.name, trainer.faction)
- local coord_text = ""
-
- if trainer.coord_x ~= 0 and trainer.coord_y ~= 0 then
- coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. trainer.coord_x .. ", " .. trainer.coord_y .. ")")
- end
- local t = AcquireTable()
-
- t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["trainer"], L["Trainer"])..":", name)
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- if coord_text == "" and hide_location then
- return entry_index
- end
- t = AcquireTable()
- t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], trainer.location), coord_text)
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- -- Right now PVP obtained items are located on vendors so they have the vendor and PVP flag.
- -- We need to display the vendor in the drop down if we want to see vendors or if we want to see PVP
- -- This allows us to select PVP only and to see just the PVP recipes
- local function ExpandVendorData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local vendor = private.vendor_list[id_num]
-
- if not CanDisplayFaction(vendor.faction) then
- return entry_index
- end
-
- local name = ColorNameByFaction(vendor.name, vendor.faction)
- local coord_text = ""
-
- if vendor.coord_x ~= 0 and vendor.coord_y ~= 0 then
- coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. vendor.coord_x .. ", " .. vendor.coord_y .. ")")
- end
- local t = AcquireTable()
- local quantity = vendor.item_list[recipe_id]
-
- t.text = string.format("%s%s %s%s", PADDING,
- hide_type and "" or SetTextColor(CATEGORY_COLORS["vendor"], L["Vendor"])..":", name,
- type(quantity) == "number" and SetTextColor(BASIC_COLORS["white"], string.format(" (%d)", quantity)) or "")
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- if coord_text == "" and hide_location then
- return entry_index
- end
- t = AcquireTable()
- t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], vendor.location), coord_text)
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- -- Mobs can be in instances, raids, or specific mob related drops.
- local function ExpandMobData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local mob = private.mob_list[id_num]
- local coord_text = ""
-
- if mob.coord_x ~= 0 and mob.coord_y ~= 0 then
- coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. mob.coord_x .. ", " .. mob.coord_y .. ")")
- end
- local t = AcquireTable()
-
- t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["mobdrop"], L["Mob Drop"])..":", SetTextColor(private.reputation_colors["hostile"], mob.name))
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- if coord_text == "" and hide_location then
- return entry_index
- end
- t = AcquireTable()
- t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], mob.location), coord_text)
- t.recipe_id = recipe_id
- t.npc_id = id_num
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- local function ExpandQuestData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local quest = private.quest_list[id_num]
-
- if not CanDisplayFaction(quest.faction) then
- return entry_index
- end
-
- local name = ColorNameByFaction(private.quest_names[id_num], quest.faction)
- local coord_text = ""
-
- if quest.coord_x ~= 0 and quest.coord_y ~= 0 then
- coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. quest.coord_x .. ", " .. quest.coord_y .. ")")
- end
- local t = AcquireTable()
-
- t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["quest"], L["Quest"])..":", name)
- t.recipe_id = recipe_id
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- if coord_text == "" and hide_location then
- return entry_index
- end
- t = AcquireTable()
- t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], quest.location), coord_text)
- t.recipe_id = recipe_id
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- local function ExpandSeasonalData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local t = AcquireTable()
-
- t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["seasonal"], private.acquire_names[A.SEASONAL])..":",
- SetTextColor(CATEGORY_COLORS["seasonal"], private.seasonal_list[id_num].name))
- t.recipe_id = recipe_id
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- local function ExpandReputationData(entry_index, entry_type, parent_entry, vendor_id, rep_id, rep_level, recipe_id, hide_location, hide_type)
- local rep_vendor = private.vendor_list[vendor_id]
-
- if not CanDisplayFaction(rep_vendor.faction) then
- return entry_index
- end
-
- if not faction_strings then
- local rep_color = private.reputation_colors
-
- faction_strings = {
- [0] = SetTextColor(rep_color["neutral"], FACTION_NEUTRAL .. " : "),
- [1] = SetTextColor(rep_color["friendly"], BFAC["Friendly"] .. " : "),
- [2] = SetTextColor(rep_color["honored"], BFAC["Honored"] .. " : "),
- [3] = SetTextColor(rep_color["revered"], BFAC["Revered"] .. " : "),
- [4] = SetTextColor(rep_color["exalted"], BFAC["Exalted"] .. " : ")
- }
- end
-
- local name = ColorNameByFaction(rep_vendor.name, rep_vendor.faction)
- local t = AcquireTable()
-
- t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["reputation"], _G.REPUTATION)..":",
- SetTextColor(CATEGORY_COLORS["repname"], private.reputation_list[rep_id].name))
- t.recipe_id = recipe_id
- t.npc_id = vendor_id
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- t = AcquireTable()
- t.text = PADDING .. PADDING .. faction_strings[rep_level] .. name
- t.recipe_id = recipe_id
- t.npc_id = vendor_id
-
- entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
-
- local coord_text = ""
-
- if rep_vendor.coord_x ~= 0 and rep_vendor.coord_y ~= 0 then
- coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. rep_vendor.coord_x .. ", " .. rep_vendor.coord_y .. ")")
- end
-
- if coord_text == "" and hide_location then
- return entry_index
- end
- t = AcquireTable()
- t.text = string.format("%s%s%s%s %s", PADDING, PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], rep_vendor.location), coord_text)
- t.recipe_id = recipe_id
- t.npc_id = vendor_id
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- local function ExpandWorldDropData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local _, _, _, hex_color = GetItemQualityColor(private.recipe_list[recipe_id].quality)
- local drop_location = type(id_num) == "string" and BZ[id_num] or nil
-
- if drop_location then
- drop_location = string.format(": %s", SetTextColor(CATEGORY_COLORS["location"], drop_location))
- else
- drop_location = ""
- end
- local t = AcquireTable()
-
- t.text = string.format("%s%s%s|r%s", PADDING, hex_color, L["World Drop"], drop_location)
- t.recipe_id = recipe_id
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- local function ExpandCustomData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- local t = AcquireTable()
-
- t.text = PADDING .. SetTextColor(CATEGORY_COLORS["custom"], private.custom_list[id_num].name)
- t.recipe_id = recipe_id
-
- return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- end
-
- function ListFrame:ExpandAcquireData(entry_index, entry_type, parent_entry, acquire_type, acquire_data, recipe_id, hide_location, hide_type)
- local obtain_filters = addon.db.profile.filters.obtain
-
- for id_num, info in pairs(acquire_data) do
- if acquire_type == A.TRAINER and obtain_filters.trainer then
- entry_index = ExpandTrainerData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- elseif acquire_type == A.VENDOR and (obtain_filters.vendor or obtain_filters.pvp) then
- entry_index = ExpandVendorData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- elseif acquire_type == A.MOB_DROP and (obtain_filters.mobdrop or obtain_filters.instance or obtain_filters.raid) then
- entry_index = ExpandMobData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- elseif acquire_type == A.QUEST and obtain_filters.quest then
- entry_index = ExpandQuestData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- elseif acquire_type == A.SEASONAL and obtain_filters.seasonal then
- entry_index = ExpandSeasonalData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- elseif acquire_type == A.REPUTATION then
- for rep_level, level_info in pairs(info) do
- for vendor_id in pairs(level_info) do
- entry_index = ExpandReputationData(entry_index, entry_type, parent_entry, vendor_id, id_num, rep_level, recipe_id, hide_location, hide_type)
- end
- end
- elseif acquire_type == A.WORLD_DROP and obtain_filters.worlddrop then
- if not hide_type then
- entry_index = ExpandWorldDropData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- end
- elseif acquire_type == A.CUSTOM then
- if not hide_type then
- entry_index = ExpandCustomData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
- end
- --@alpha@
- elseif acquire_type > A_MAX then
- local t = AcquireTable()
-
- t.text = "Unhandled Acquire Case - Type: " .. acquire_type
- t.recipe_id = recipe_id
-
- entry_index = self:InsertEntry(t, parent_entry, entry_index, entry_type, true)
- --@end-alpha@
- end
- end -- for
- return entry_index
- end
-
- -- This function is called when an un-expanded entry in the list has been clicked.
- function ListFrame:ExpandEntry(entry_index, expand_mode)
- local orig_index = entry_index
- local current_entry = self.entries[orig_index]
- local expand_all = expand_mode == "deep"
- local search_box = MainPanel.search_editbox
- local current_tab = MainPanel.tabs[MainPanel.current_tab]
- local prof_name = ORDERED_PROFESSIONS[MainPanel.profession]
-
- -- Entry_index is the position in self.entries that we want to expand. Since we are expanding the current entry, the return
- -- value should be the index of the next button after the expansion occurs
- entry_index = entry_index + 1
-
- current_tab:ModifyEntry(current_entry, true)
-
- -- This entry was generated using sorting based on Acquisition.
- if current_entry.acquire_id then
- local acquire_id = current_entry.acquire_id
-
- if current_entry.type == "header" then
- local recipe_list = private.acquire_list[acquire_id].recipes
- local sorted_recipes = addon.sorted_recipes
-
- private.SortRecipeList(recipe_list)
-
- for index = 1, #sorted_recipes do
- local spell_id = sorted_recipes[index]
- local recipe_entry = private.recipe_list[spell_id]
-
- if recipe_entry:HasState("VISIBLE") and search_box:MatchesRecipe(recipe_entry) then
- local t = AcquireTable()
- local expand = false
- local type = "subheader"
-
- if acquire_id == A.WORLD_DROP or acquire_id == A.CUSTOM then
- expand = true
- type = "entry"
- end
- local is_expanded = current_tab[prof_name.." expanded"][spell_id] and current_tab[prof_name.." expanded"][private.acquire_names[acquire_id]]
-
- t.text = recipe_entry:GetDisplayName()
- t.recipe_id = spell_id
- t.acquire_id = acquire_id
-
- entry_index = self:InsertEntry(t, current_entry, entry_index, type, expand or is_expanded, expand_all or is_expanded)
- end
- end
- elseif current_entry.type == "subheader" then
- for acquire_type, acquire_data in pairs(private.recipe_list[current_entry.recipe_id].acquire_data) do
- if acquire_type == acquire_id then
- entry_index = self:ExpandAcquireData(entry_index, "subentry", current_entry, acquire_type, acquire_data, current_entry.recipe_id, false, true)
- end
- end
- end
- return entry_index
- end
-
- -- This entry was generated using sorting based on Location.
- if current_entry.location_id then
- local location_id = current_entry.location_id
-
- if current_entry.type == "header" then
- local recipe_list = private.location_list[location_id].recipes
- local sorted_recipes = addon.sorted_recipes
-
- private.SortRecipeList(recipe_list)
-
- for index = 1, #sorted_recipes do
- local spell_id = sorted_recipes[index]
- local recipe_entry = private.recipe_list[spell_id]
-
- if recipe_entry:HasState("VISIBLE") and search_box:MatchesRecipe(recipe_entry) then
- local expand = false
- local type = "subheader"
- local t = AcquireTable()
-
- -- Add World Drop entries as normal entries.
- if recipe_list[spell_id] == "world_drop" then
- expand = true
- type = "entry"
- end
- local is_expanded = current_tab[prof_name.." expanded"][spell_id] and current_tab[prof_name.." expanded"][location_id]
-
- t.text = recipe_entry:GetDisplayName()
- t.recipe_id = spell_id
- t.location_id = location_id
-
- entry_index = self:InsertEntry(t, current_entry, entry_index, type, expand or is_expanded, expand_all or is_expanded)
- end
- end
- elseif current_entry.type == "subheader" then
- local recipe_entry = private.recipe_list[current_entry.recipe_id]
-
- -- World Drops are not handled here because they are of type "entry".
- for acquire_type, acquire_data in pairs(recipe_entry.acquire_data) do
- for id_num, info in pairs(acquire_data) do
- -- Only expand an acquisition entry if it is from this location.
- if acquire_type == A.TRAINER and private.trainer_list[id_num].location == location_id then
- entry_index = ExpandTrainerData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true)
- elseif acquire_type == A.VENDOR and private.vendor_list[id_num].location == location_id then
- entry_index = ExpandVendorData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true)
- elseif acquire_type == A.MOB_DROP and private.mob_list[id_num].location == location_id then
- entry_index = ExpandMobData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true)
- elseif acquire_type == A.QUEST and private.quest_list[id_num].location == location_id then
- entry_index = ExpandQuestData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true)
- elseif acquire_type == A.SEASONAL and private.seasonal_list[id_num].location == location_id then
- -- Hide the acquire type for this - it will already show up in the location list as "World Events".
- entry_index = ExpandSeasonalData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true, true)
- elseif acquire_type == A.CUSTOM and private.custom_list[id_num].location == location_id then
- entry_index = ExpandCustomData(entry_index, "subentry", current_entry,
- id_num, current_entry.recipe_id, true, true)
- elseif acquire_type == A.REPUTATION then
- for rep_level, level_info in pairs(info) do
- for vendor_id in pairs(level_info) do
- if private.vendor_list[vendor_id].location == location_id then
- entry_index = ExpandReputationData(entry_index, "subentry", current_entry,
- vendor_id, id_num, rep_level, current_entry.recipe_id, true)
- end
- end
- end
- end
- end
- end
- end
- return entry_index
- end
-
- -- Normal entry - expand all acquire types.
- local recipe_id = self.entries[orig_index].recipe_id
-
- for acquire_type, acquire_data in pairs(private.recipe_list[recipe_id].acquire_data) do
- entry_index = self:ExpandAcquireData(entry_index, "entry", current_entry,
- acquire_type, acquire_data, recipe_id)
- end
- return entry_index
- end
-end -- do
-
--------------------------------------------------------------------------------
-- Create MainPanel.progress_bar and set its scripts
-------------------------------------------------------------------------------
do
@@ -2933,6 +1402,7 @@ local function InitializeFrame()
-------------------------------------------------------------------------------
-- Initialize components defined in other files.
-------------------------------------------------------------------------------
+ private.InitializeListFrame()
private.InitializeTabs()
-------------------------------------------------------------------------------
@@ -3153,7 +1623,7 @@ local function InitializeFrame()
general_frame[class]:SetChecked(true)
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
general_frame.class_toggle = class_toggle
@@ -3244,7 +1714,7 @@ local function InitializeFrame()
item_frame[armor]:SetChecked(toggle)
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
item_frame.armor_toggle = armor_toggle
@@ -3284,7 +1754,7 @@ local function InitializeFrame()
end
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
item_frame.weapon_toggle = weapon_toggle
@@ -3520,7 +1990,7 @@ local function InitializeFrame()
expansion0_frame[reputation]:SetChecked(filterdb[reputation])
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
end -- do-block
@@ -3583,7 +2053,7 @@ local function InitializeFrame()
expansion1_frame[reputation]:SetChecked(filterdb[reputation])
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
end -- do-block
@@ -3656,7 +2126,7 @@ local function InitializeFrame()
expansion2_frame[reputation]:SetChecked(filterdb[reputation])
end
MainPanel:UpdateTitle()
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end)
end -- do-block
@@ -3902,7 +2372,7 @@ do
editbox:SetText(editbox.prev_search or _G.SEARCH)
-- If there is no current tab, this is the first time the panel has been
- -- shown so things must be initialized. In this case, ListFrame:Update()
+ -- shown so things must be initialized. In this case, MainPanel.list_frame:Update()
-- will be called by the tab's OnClick handler.
if not self.current_tab then
local current_tab = self.tabs[addon.db.profile.current_tab]
@@ -3912,7 +2382,7 @@ do
self.current_tab = addon.db.profile.current_tab
else
- ListFrame:Update(nil, false)
+ MainPanel.list_frame:Update(nil, false)
end
self.sort_button:SetTextures()
self.filter_toggle:SetTextures()
diff --git a/Interface/List.lua b/Interface/List.lua
new file mode 100644
index 0000000..da652ab
--- /dev/null
+++ b/Interface/List.lua
@@ -0,0 +1,1566 @@
+-------------------------------------------------------------------------------
+-- Localized Lua globals.
+-------------------------------------------------------------------------------
+local _G = getfenv(0)
+
+local string = _G.string
+local table = _G.table
+
+-------------------------------------------------------------------------------
+-- AddOn namespace.
+-------------------------------------------------------------------------------
+local LibStub = LibStub
+
+local MODNAME = "Ackis Recipe List"
+local addon = LibStub("AceAddon-3.0"):GetAddon(MODNAME)
+
+local BFAC = LibStub("LibBabble-Faction-3.0"):GetLookupTable()
+local BZ = LibStub("LibBabble-Zone-3.0"):GetLookupTable()
+local L = LibStub("AceLocale-3.0"):GetLocale(MODNAME)
+local QTip = LibStub("LibQTip-1.0")
+
+-- Set up the private intra-file namespace.
+local private = select(2, ...)
+
+local Player = private.Player
+
+-------------------------------------------------------------------------------
+-- Constants
+-------------------------------------------------------------------------------
+local NUM_RECIPE_LINES = 25
+local SCROLL_DEPTH = 5
+local LISTFRAME_WIDTH = 295
+
+local CATEGORY_COLORS = private.category_colors
+local BASIC_COLORS = private.basic_colors
+
+local SF = private.recipe_state_flags
+local COMMON_FLAGS_1 = private.common_flags_word1
+
+local A = private.acquire_types
+local A_MAX = 9
+
+local FACTION_NEUTRAL = BFAC["Neutral"]
+
+-------------------------------------------------------------------------------
+-- Upvalues
+-------------------------------------------------------------------------------
+local ListItem_ShowTooltip
+
+local acquire_tip
+local spell_tip
+
+local AcquireTable = private.AcquireTable
+local ReleaseTable = private.ReleaseTable
+local SetTextColor = private.SetTextColor
+local GenericCreateButton = private.GenericCreateButton
+
+-------------------------------------------------------------------------------
+-- Frame creation and anchoring
+-------------------------------------------------------------------------------
+function private.InitializeListFrame()
+ local MainPanel = addon.Frame
+ local ListFrame = CreateFrame("Frame", nil, MainPanel)
+
+ MainPanel.list_frame = ListFrame
+
+ ListFrame:SetHeight(335)
+ ListFrame:SetWidth(LISTFRAME_WIDTH)
+ ListFrame:SetPoint("TOPLEFT", MainPanel, "TOPLEFT", 22, -75)
+ ListFrame:SetBackdrop({
+ bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
+ tile = true,
+ tileSize = 16,
+ })
+ ListFrame:SetBackdropColor(1, 1, 1)
+ ListFrame:EnableMouse(true)
+ ListFrame:EnableMouseWheel(true)
+
+ -------------------------------------------------------------------------------
+ -- Scroll bar.
+ -------------------------------------------------------------------------------
+ local ScrollBar = CreateFrame("Slider", nil, ListFrame)
+
+ ScrollBar:SetPoint("TOPLEFT", ListFrame, "TOPRIGHT", 5, -11)
+ ScrollBar:SetPoint("BOTTOMLEFT", ListFrame, "BOTTOMRIGHT", 5, 12)
+ ScrollBar:SetWidth(24)
+
+ ScrollBar:EnableMouseWheel(true)
+ ScrollBar:SetOrientation("VERTICAL")
+
+ ScrollBar:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
+ ScrollBar:SetMinMaxValues(0, 1)
+ ScrollBar:SetValueStep(1)
+
+ ListFrame.scroll_bar = ScrollBar
+
+ local ScrollUpButton = CreateFrame("Button", nil, ScrollBar, "UIPanelScrollUpButtonTemplate")
+
+ ScrollUpButton:SetHeight(16)
+ ScrollUpButton:SetWidth(18)
+ ScrollUpButton:SetPoint("BOTTOM", ScrollBar, "TOP", 0, -4)
+
+ local ScrollDownButton = CreateFrame("Button", nil, ScrollBar,"UIPanelScrollDownButtonTemplate")
+
+ ScrollDownButton:SetHeight(16)
+ ScrollDownButton:SetWidth(18)
+ ScrollDownButton:SetPoint("TOP", ScrollBar, "BOTTOM", 0, 4)
+
+ local function ScrollBar_Scroll(delta)
+ if not ScrollBar:IsShown() then
+ return
+ end
+ local cur_val = ScrollBar:GetValue()
+ local min_val, max_val = ScrollBar:GetMinMaxValues()
+
+ if delta < 0 and cur_val < max_val then
+ cur_val = math.min(max_val, cur_val + SCROLL_DEPTH)
+ ScrollBar:SetValue(cur_val)
+ elseif delta > 0 and cur_val > min_val then
+ cur_val = math.max(min_val, cur_val - SCROLL_DEPTH)
+ ScrollBar:SetValue(cur_val)
+ end
+ end
+
+ ScrollUpButton:SetScript("OnClick",
+ function(self, button, down)
+ if _G.IsAltKeyDown() then
+ local min_val = ScrollBar:GetMinMaxValues()
+ ScrollBar:SetValue(min_val)
+ else
+ ScrollBar_Scroll(1)
+ end
+ end)
+
+ ScrollDownButton:SetScript("OnClick",
+ function(self, button, down)
+ if _G.IsAltKeyDown() then
+ local _, max_val = ScrollBar:GetMinMaxValues()
+ ScrollBar:SetValue(max_val)
+ else
+ ScrollBar_Scroll(-1)
+ end
+ end)
+
+ ScrollBar:SetScript("OnMouseWheel",
+ function(self, delta)
+ ScrollBar_Scroll(delta)
+ end)
+
+ ListFrame:SetScript("OnMouseWheel",
+ function(self, delta)
+ ScrollBar_Scroll(delta)
+ end)
+
+ -- This can be called either from ListFrame's OnMouseWheel script, manually
+ -- sliding the thumb, or from clicking the up/down buttons.
+ ScrollBar:SetScript("OnValueChanged",
+ function(self, value)
+ local min_val, max_val = self:GetMinMaxValues()
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+ local member = "profession_"..MainPanel.profession.."_scroll_value"
+
+ current_tab[member] = value
+
+ if value == min_val then
+ ScrollUpButton:Disable()
+ ScrollDownButton:Enable()
+ elseif value == max_val then
+ ScrollUpButton:Enable()
+ ScrollDownButton:Disable()
+ else
+ ScrollUpButton:Enable()
+ ScrollDownButton:Enable()
+ end
+ ListFrame:Update(nil, true)
+ end)
+
+ local function Button_OnEnter(self)
+ ListItem_ShowTooltip(self, ListFrame.entries[self.string_index])
+ end
+
+ local function Button_OnLeave()
+ QTip:Release(acquire_tip)
+ spell_tip:Hide()
+ end
+
+ local function Bar_OnEnter(self)
+ ListItem_ShowTooltip(self, ListFrame.entries[self.string_index])
+ end
+
+ local function Bar_OnLeave()
+ QTip:Release(acquire_tip)
+ spell_tip:Hide()
+ end
+
+ local function ListItem_OnClick(self, button, down)
+ local clickedIndex = self.string_index
+
+ -- Don't do anything if they've clicked on an empty button
+ if not clickedIndex or clickedIndex == 0 then
+ return
+ end
+ local clicked_line = ListFrame.entries[clickedIndex]
+ local traverseIndex = 0
+
+ if not clicked_line then
+ return
+ end
+ -- First, check if this is a "modified" click, and react appropriately
+ if clicked_line.recipe_id and _G.IsModifierKeyDown() then
+ if _G.IsControlKeyDown() and _G.IsShiftKeyDown() then
+ addon:AddWaypoint(clicked_line.recipe_id, clicked_line.acquire_id, clicked_line.location_id, clicked_line.npc_id)
+ elseif _G.IsShiftKeyDown() then
+ local itemID = private.recipe_list[clicked_line.recipe_id].item_id
+
+ if itemID then
+ local _, itemLink = _G.GetItemInfo(itemID)
+
+ if itemLink then
+ local edit_box = _G.ChatEdit_ChooseBoxForSend()
+
+ _G.ChatEdit_ActivateChat(edit_box)
+ edit_box:Insert(itemLink)
+ else
+ addon:Print(L["NoItemLink"])
+ end
+ else
+ addon:Print(L["NoItemLink"])
+ end
+ elseif _G.IsControlKeyDown() then
+ local edit_box = _G.ChatEdit_ChooseBoxForSend()
+
+ _G.ChatEdit_ActivateChat(edit_box)
+ edit_box:Insert(GetSpellLink(private.recipe_list[clicked_line.recipe_id].spell_id))
+ elseif _G.IsAltKeyDown() then
+ local exclusion_list = addon.db.profile.exclusionlist
+ local recipe_id = clicked_line.recipe_id
+
+ exclusion_list[recipe_id] = (not exclusion_list[recipe_id] and true or nil)
+ ListFrame:Update(nil, false)
+ end
+ elseif clicked_line.type == "header" or clicked_line.type == "subheader" then
+ -- three possibilities here (all with no modifiers)
+ -- 1) We clicked on the recipe button on a closed recipe
+ -- 2) We clicked on the recipe button of an open recipe
+ -- 3) we clicked on the expanded text of an open recipe
+ if clicked_line.is_expanded then
+ traverseIndex = clickedIndex + 1
+
+ local check_type = clicked_line.type
+ local entry = ListFrame.entries[traverseIndex]
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+
+ -- get rid of our expanded lines
+ while entry and entry.type ~= check_type do
+ -- Headers are never removed.
+ if entry.type == "header" then
+ break
+ end
+ current_tab:ModifyEntry(entry, false)
+ ReleaseTable(table.remove(ListFrame.entries, traverseIndex))
+ entry = ListFrame.entries[traverseIndex]
+
+ if not entry then
+ break
+ end
+ end
+ current_tab:ModifyEntry(clicked_line, false)
+ clicked_line.is_expanded = false
+ else
+ ListFrame:ExpandEntry(clickedIndex)
+ clicked_line.is_expanded = true
+ end
+ else
+ -- clicked_line is an expanded entry - find the index for its parent, and remove all of the parent's child entries.
+ local parent = clicked_line.parent
+
+ if parent then
+ local parent_index
+ local entries = ListFrame.entries
+
+ for index = 1, #entries do
+ if entries[index] == parent then
+ parent_index = index
+ break
+ end
+ end
+
+ if not parent_index then
+ addon:Debug("clicked_line (%s): parent wasn't found in ListFrame.entries", clicked_line.text)
+ return
+ end
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+
+ parent.is_expanded = false
+ current_tab:ModifyEntry(parent, false)
+
+ local child_index = parent_index + 1
+
+ while entries[child_index] and entries[child_index].parent == parent do
+ ReleaseTable(table.remove(entries, child_index))
+ end
+ else
+ addon:Debug("Error: clicked_line has no parent.")
+ end
+ end
+ QTip:Release(acquire_tip)
+ spell_tip:Hide()
+
+ ListFrame:Update(nil, true)
+ end
+
+ -------------------------------------------------------------------------------
+ -- The state and entry buttons and the container frames which hold them.
+ -------------------------------------------------------------------------------
+ ListFrame.entries = {}
+ ListFrame.button_containers = {}
+ ListFrame.state_buttons = {}
+ ListFrame.entry_buttons = {}
+
+ for i = 1, NUM_RECIPE_LINES do
+ local cur_container = CreateFrame("Frame", nil, ListFrame)
+
+ cur_container:SetHeight(16)
+ cur_container:SetWidth(LISTFRAME_WIDTH)
+
+ local cur_state = GenericCreateButton(nil, ListFrame, 16, 16, nil, nil, nil, nil, 2)
+ local cur_entry = GenericCreateButton(nil, ListFrame, 16, LISTFRAME_WIDTH, "GameFontNormalSmall", "Blort", "LEFT", nil, 0)
+
+ if i == 1 then
+ cur_container:SetPoint("TOPLEFT", ListFrame, "TOPLEFT", 0, 0)
+ cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
+ cur_entry:SetPoint("TOPLEFT", cur_state, "TOPRIGHT", -3, 0)
+ else
+ local prev_container = ListFrame.button_containers[i - 1]
+
+ cur_container:SetPoint("TOPLEFT", prev_container, "BOTTOMLEFT", 0, 3)
+ cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
+ cur_entry:SetPoint("TOPLEFT", cur_state, "TOPRIGHT", -3, 0)
+ end
+ cur_state.container = cur_container
+
+ cur_state:SetScript("OnClick", ListItem_OnClick)
+ cur_entry:SetScript("OnClick", ListItem_OnClick)
+
+ ListFrame.button_containers[i] = cur_container
+ ListFrame.state_buttons[i] = cur_state
+ ListFrame.entry_buttons[i] = cur_entry
+ end
+
+ function ListFrame:InsertEntry(entry, parent_entry, entry_index, entry_type, entry_expanded, expand_mode)
+ entry.type = entry_type
+
+ if parent_entry then
+ if parent_entry ~= entry then
+ entry.parent = parent_entry
+
+ local recipe_id = parent_entry.recipe_id
+ local acquire_id = parent_entry.acquire_id
+ local location_id = parent_entry.location_id
+ local npc_id = parent_entry.npc_id
+
+ if recipe_id then
+ entry.recipe_id = recipe_id
+ end
+
+ if acquire_id then
+ entry.acquire_id = acquire_id
+ end
+
+ if location_id then
+ entry.location_id = location_id
+ end
+
+ if npc_id then
+ entry.npc_id = npc_id
+ end
+ else
+ addon:Debug("Attempting to parent an entry to itself.")
+ end
+ elseif entry.type ~= "header" then
+ addon:Debug("Non-header entry without a parent: %s - %s", entry.type, entry.text)
+ end
+ local insert_index = entry_index
+
+ -- If we have acquire information for this entry, push the data table into the list
+ -- and start processing the acquires.
+ if expand_mode then
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+
+ entry.is_expanded = true
+ table.insert(self.entries, insert_index, entry)
+
+ current_tab:ModifyEntry(entry, entry_expanded)
+
+ if entry_type == "header" or entry_type == "subheader" then
+ insert_index = self:ExpandEntry(insert_index, expand_mode)
+ else
+ insert_index = insert_index + 1
+ end
+ else
+ entry.is_expanded = entry_expanded
+ table.insert(self.entries, insert_index, entry)
+
+ insert_index = insert_index + 1
+ end
+ return insert_index
+ end
+
+ function ListFrame:Initialize(expand_mode)
+ for i = 1, #self.entries do
+ ReleaseTable(self.entries[i])
+ end
+ table.wipe(self.entries)
+
+ addon:UpdateFilters(MainPanel.is_linked)
+
+ -------------------------------------------------------------------------------
+ -- Mark all exclusions in the recipe database to not be displayed, and update
+ -- the player's known and unknown counts.
+ -------------------------------------------------------------------------------
+ local exclusion_list = addon.db.profile.exclusionlist
+ local ignored = not addon.db.profile.ignoreexclusionlist
+ local recipe_list = private.recipe_list
+ local current_prof = private.ordered_professions[MainPanel.profession]
+ local known_count = 0
+ local unknown_count = 0
+
+ for spell_id in pairs(exclusion_list) do
+ local recipe = recipe_list[spell_id]
+
+ if recipe then
+ if recipe:HasState("KNOWN") and recipe.profession == current_prof then
+ known_count = known_count + 1
+ elseif recipe_profession == current_prof then
+ unknown_count = unknown_count + 1
+ end
+ end
+ end
+ Player.excluded_recipes_known = known_count
+ Player.excluded_recipes_unknown = unknown_count
+
+ -------------------------------------------------------------------------------
+ -- Initialize the expand button and entries for the current tab.
+ -------------------------------------------------------------------------------
+ local current_tab = MainPanel.tabs[addon.db.profile.current_tab]
+ local expanded_button = current_tab["expand_button_"..MainPanel.profession]
+
+ if expanded_button then
+ MainPanel.expand_button:Expand(current_tab)
+ else
+ MainPanel.expand_button:Contract(current_tab)
+ end
+ local recipe_count = current_tab:Initialize(expand_mode)
+
+ -------------------------------------------------------------------------------
+ -- Update the progress bar display.
+ -------------------------------------------------------------------------------
+ local profile = addon.db.profile
+ local max_value = profile.includefiltered and Player.recipes_total or Player.recipes_total_filtered
+ local cur_value = profile.includefiltered and Player.recipes_known or Player.recipes_known_filtered
+
+ if not profile.includeexcluded and not profile.ignoreexclusionlist then
+ max_value = max_value - Player.excluded_recipes_known
+ end
+ local progress_bar = MainPanel.progress_bar
+
+ progress_bar:SetMinMaxValues(0, max_value)
+ progress_bar:SetValue(cur_value)
+
+ local percentage = cur_value / max_value * 100
+
+ if (floor(percentage) < 101) and cur_value >= 0 and max_value >= 0 then
+ local results = string.format(_G.SINGLE_PAGE_RESULTS_TEMPLATE, recipe_count)
+ progress_bar.text:SetFormattedText("%d/%d - %1.2f%% (%s)", cur_value, max_value, percentage, results)
+ else
+ progress_bar.text:SetFormattedText("%s", L["NOT_YET_SCANNED"])
+ end
+ end
+
+ -- Reset the current buttons/lines
+ function ListFrame:ClearLines()
+ local font_object = addon.db.profile.frameopts.small_list_font and "GameFontNormalSmall" or "GameFontNormal"
+
+ for i = 1, NUM_RECIPE_LINES do
+ local entry = self.entry_buttons[i]
+ local state = self.state_buttons[i]
+
+ entry.string_index = 0
+ entry.text:SetFontObject(font_object)
+
+ entry:SetText("")
+ entry:SetScript("OnEnter", nil)
+ entry:SetScript("OnLeave", nil)
+ entry:SetWidth(LISTFRAME_WIDTH)
+ entry:Disable()
+
+ state.string_index = 0
+
+ state:Hide()
+ state:SetScript("OnEnter", nil)
+ state:SetScript("OnLeave", nil)
+ state:Disable()
+
+ state:ClearAllPoints()
+ end
+ end
+
+ function ListFrame:Update(expand_mode, refresh)
+ if not refresh then
+ self:Initialize(expand_mode)
+ end
+
+ local num_entries = #self.entries
+
+ if num_entries == 0 then
+ self:ClearLines()
+
+ -- disable expand button, it's useless here and would spam the same error again
+ MainPanel.expand_button:SetNormalFontObject("GameFontDisableSmall")
+ MainPanel.expand_button:Disable()
+ self.scroll_bar:Hide()
+
+ local showpopup = false
+
+ if not addon.db.profile.hidepopup then
+ showpopup = true
+ end
+
+ -- If we haven't run this before we'll show pop-ups for the first time.
+ if addon.db.profile.addonversion ~= addon.version then
+ addon.db.profile.addonversion = addon.version
+ showpopup = true
+ end
+ local editbox_text = SearchBox:GetText()
+
+ if Player.recipes_total == 0 then
+ if showpopup then
+ _G.StaticPopup_Show("ARL_NOTSCANNED")
+ end
+ elseif Player.recipes_known == Player.recipes_total then
+ if showpopup then
+ _G.StaticPopup_Show("ARL_ALLKNOWN")
+ end
+ elseif (Player.recipes_total_filtered - Player.recipes_known_filtered) == 0 then
+ if showpopup then
+ _G.StaticPopup_Show("ARL_ALLFILTERED")
+ end
+ elseif Player.excluded_recipes_unknown ~= 0 then
+ if showpopup then
+ _G.StaticPopup_Show("ARL_ALLEXCLUDED")
+ end
+ elseif editbox_text ~= "" and editbox_text ~= _G.SEARCH then
+ _G.StaticPopup_Show("ARL_SEARCHFILTERED")
+ else
+ addon:Print(L["NO_DISPLAY"])
+ addon:Debug("Current tab is %s", tostring(addon.db.profile.current_tab))
+ addon:Debug("recipes_total check for 0")
+ addon:Debug("recipes_total: " .. Player.recipes_total)
+ addon:Debug("recipes_total check for equal to recipes_total")
+ addon:Debug("recipes_known: " .. Player.recipes_known)
+ addon:Debug("recipes_total: " .. Player.recipes_total)
+ addon:Debug("recipes_total_filtered - recipes_known_filtered = 0")
+ addon:Debug("recipes_total_filtered: " .. Player.recipes_total_filtered)
+ addon:Debug("recipes_known_filtered: " .. Player.recipes_known_filtered)
+ addon:Debug("excluded_recipes_unknown ~= 0")
+ addon:Debug("excluded_recipes_unknown: " .. Player.excluded_recipes_unknown)
+ end
+ return
+ end
+ local offset = 0
+
+ addon:ClosePopups()
+
+ MainPanel.expand_button:SetNormalFontObject("GameFontNormalSmall")
+ MainPanel.expand_button:Enable()
+
+ if num_entries <= NUM_RECIPE_LINES then
+ self.scroll_bar:Hide()
+ else
+ local max_val = num_entries - NUM_RECIPE_LINES
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+ local scroll_value = current_tab["profession_"..MainPanel.profession.."_scroll_value"] or 0
+
+ scroll_value = math.max(0, math.min(scroll_value, max_val))
+ offset = scroll_value
+
+ self.scroll_bar:SetMinMaxValues(0, math.max(0, max_val))
+ self.scroll_bar:SetValue(scroll_value)
+ self.scroll_bar:Show()
+ end
+ self:ClearLines()
+
+ local button_index = 1
+ local string_index = button_index + offset
+
+ -- Populate the buttons with new values
+ while button_index <= NUM_RECIPE_LINES and string_index <= num_entries do
+ local cur_state = self.state_buttons[button_index]
+ local cur_entry = self.entries[string_index]
+
+ if cur_entry.type == "header" or cur_entry.type == "subheader" then
+ cur_state:Show()
+
+ if cur_entry.is_expanded then
+ cur_state:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up")
+ cur_state:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down")
+ cur_state:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
+ cur_state:SetDisabledTexture("Interface\\Buttons\\UI-MinusButton-Disabled")
+ else
+ cur_state:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
+ cur_state:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down")
+ cur_state:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
+ cur_state:SetDisabledTexture("Interface\\Buttons\\UI-PlusButton-Disabled")
+ end
+ cur_state.string_index = string_index
+ cur_state:SetScript("OnEnter", Button_OnEnter)
+ cur_state:SetScript("OnLeave", Button_OnLeave)
+ cur_state:Enable()
+ else
+ cur_state:Hide()
+ cur_state:Disable()
+ end
+ local cur_container = cur_state.container
+ local cur_button = self.entry_buttons[button_index]
+
+ if cur_entry.type == "header" or cur_entry.type == "entry" then
+ cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 0, 0)
+ elseif cur_entry.type == "subheader" or cur_entry.type == "subentry" then
+ cur_state:SetPoint("TOPLEFT", cur_container, "TOPLEFT", 15, 0)
+ cur_button:SetWidth(LISTFRAME_WIDTH - 15)
+ end
+ cur_button.string_index = string_index
+ cur_button:SetText(cur_entry.text)
+ cur_button:SetScript("OnEnter", Bar_OnEnter)
+ cur_button:SetScript("OnLeave", Bar_OnLeave)
+ cur_button:Enable()
+
+ button_index = button_index + 1
+ string_index = string_index + 1
+ end
+ button_index = 1
+ string_index = button_index + offset
+
+ -- This function could possibly have been called from a mouse click or by scrolling.
+ -- Since, in those cases, the list entries have changed, the mouse is likely over a different entry - a tooltip should be generated for it.
+ while button_index <= NUM_RECIPE_LINES and string_index <= num_entries do
+ local cur_state = self.state_buttons[button_index]
+ local cur_button = self.entry_buttons[button_index]
+
+ if cur_state:IsMouseOver() then
+ Button_OnEnter(cur_state)
+ break
+ elseif cur_button:IsMouseOver() then
+ Bar_OnEnter(cur_button)
+ break
+ end
+ button_index = button_index + 1
+ string_index = string_index + 1
+ end
+ end
+
+ -------------------------------------------------------------------------------
+ -- Functions and data pertaining to individual list entries.
+ -------------------------------------------------------------------------------
+ local faction_strings
+
+ local function CanDisplayFaction(faction)
+ if addon.db.profile.filters.general.faction then
+ return true
+ end
+ return (not faction or faction == BFAC[Player.faction] or faction == FACTION_NEUTRAL)
+ end
+
+ -- Padding for list entries/subentries
+ local PADDING = " "
+
+ -- Changes the color of "name" based on faction type.
+ local function ColorNameByFaction(name, faction)
+ if faction == FACTION_NEUTRAL then
+ name = SetTextColor(private.reputation_colors["neutral"], name)
+ elseif faction == BFAC[Player.faction] then
+ name = SetTextColor(private.reputation_colors["exalted"], name)
+ else
+ name = SetTextColor(private.reputation_colors["hated"], name)
+ end
+ return name
+ end
+
+ local function ExpandTrainerData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local trainer = private.trainer_list[id_num]
+
+ if not CanDisplayFaction(trainer.faction) then
+ return entry_index
+ end
+
+ local name = ColorNameByFaction(trainer.name, trainer.faction)
+ local coord_text = ""
+
+ if trainer.coord_x ~= 0 and trainer.coord_y ~= 0 then
+ coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. trainer.coord_x .. ", " .. trainer.coord_y .. ")")
+ end
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["trainer"], L["Trainer"])..":", name)
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ if coord_text == "" and hide_location then
+ return entry_index
+ end
+ t = AcquireTable()
+ t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], trainer.location), coord_text)
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ -- Right now PVP obtained items are located on vendors so they have the vendor and PVP flag.
+ -- We need to display the vendor in the drop down if we want to see vendors or if we want to see PVP
+ -- This allows us to select PVP only and to see just the PVP recipes
+ local function ExpandVendorData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local vendor = private.vendor_list[id_num]
+
+ if not CanDisplayFaction(vendor.faction) then
+ return entry_index
+ end
+
+ local name = ColorNameByFaction(vendor.name, vendor.faction)
+ local coord_text = ""
+
+ if vendor.coord_x ~= 0 and vendor.coord_y ~= 0 then
+ coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. vendor.coord_x .. ", " .. vendor.coord_y .. ")")
+ end
+ local t = AcquireTable()
+ local quantity = vendor.item_list[recipe_id]
+
+ t.text = string.format("%s%s %s%s", PADDING,
+ hide_type and "" or SetTextColor(CATEGORY_COLORS["vendor"], L["Vendor"])..":", name,
+ type(quantity) == "number" and SetTextColor(BASIC_COLORS["white"], string.format(" (%d)", quantity)) or "")
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ if coord_text == "" and hide_location then
+ return entry_index
+ end
+ t = AcquireTable()
+ t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], vendor.location), coord_text)
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ -- Mobs can be in instances, raids, or specific mob related drops.
+ local function ExpandMobData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local mob = private.mob_list[id_num]
+ local coord_text = ""
+
+ if mob.coord_x ~= 0 and mob.coord_y ~= 0 then
+ coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. mob.coord_x .. ", " .. mob.coord_y .. ")")
+ end
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["mobdrop"], L["Mob Drop"])..":", SetTextColor(private.reputation_colors["hostile"], mob.name))
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ if coord_text == "" and hide_location then
+ return entry_index
+ end
+ t = AcquireTable()
+ t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], mob.location), coord_text)
+ t.recipe_id = recipe_id
+ t.npc_id = id_num
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandQuestData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local quest = private.quest_list[id_num]
+
+ if not CanDisplayFaction(quest.faction) then
+ return entry_index
+ end
+
+ local name = ColorNameByFaction(private.quest_names[id_num], quest.faction)
+ local coord_text = ""
+
+ if quest.coord_x ~= 0 and quest.coord_y ~= 0 then
+ coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. quest.coord_x .. ", " .. quest.coord_y .. ")")
+ end
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["quest"], L["Quest"])..":", name)
+ t.recipe_id = recipe_id
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ if coord_text == "" and hide_location then
+ return entry_index
+ end
+ t = AcquireTable()
+ t.text = string.format("%s%s%s %s", PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], quest.location), coord_text)
+ t.recipe_id = recipe_id
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandSeasonalData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["seasonal"], private.acquire_names[A.SEASONAL])..":",
+ SetTextColor(CATEGORY_COLORS["seasonal"], private.seasonal_list[id_num].name))
+ t.recipe_id = recipe_id
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandReputationData(entry_index, entry_type, parent_entry, vendor_id, rep_id, rep_level, recipe_id, hide_location, hide_type)
+ local rep_vendor = private.vendor_list[vendor_id]
+
+ if not CanDisplayFaction(rep_vendor.faction) then
+ return entry_index
+ end
+
+ if not faction_strings then
+ local rep_color = private.reputation_colors
+
+ faction_strings = {
+ [0] = SetTextColor(rep_color["neutral"], FACTION_NEUTRAL .. " : "),
+ [1] = SetTextColor(rep_color["friendly"], BFAC["Friendly"] .. " : "),
+ [2] = SetTextColor(rep_color["honored"], BFAC["Honored"] .. " : "),
+ [3] = SetTextColor(rep_color["revered"], BFAC["Revered"] .. " : "),
+ [4] = SetTextColor(rep_color["exalted"], BFAC["Exalted"] .. " : ")
+ }
+ end
+
+ local name = ColorNameByFaction(rep_vendor.name, rep_vendor.faction)
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s %s", PADDING, hide_type and "" or SetTextColor(CATEGORY_COLORS["reputation"], _G.REPUTATION)..":",
+ SetTextColor(CATEGORY_COLORS["repname"], private.reputation_list[rep_id].name))
+ t.recipe_id = recipe_id
+ t.npc_id = vendor_id
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ t = AcquireTable()
+ t.text = PADDING .. PADDING .. faction_strings[rep_level] .. name
+ t.recipe_id = recipe_id
+ t.npc_id = vendor_id
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+
+ local coord_text = ""
+
+ if rep_vendor.coord_x ~= 0 and rep_vendor.coord_y ~= 0 then
+ coord_text = SetTextColor(CATEGORY_COLORS["coords"], "(" .. rep_vendor.coord_x .. ", " .. rep_vendor.coord_y .. ")")
+ end
+
+ if coord_text == "" and hide_location then
+ return entry_index
+ end
+ t = AcquireTable()
+ t.text = string.format("%s%s%s%s %s", PADDING, PADDING, PADDING, hide_location and "" or SetTextColor(CATEGORY_COLORS["location"], rep_vendor.location), coord_text)
+ t.recipe_id = recipe_id
+ t.npc_id = vendor_id
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandWorldDropData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local _, _, _, hex_color = GetItemQualityColor(private.recipe_list[recipe_id].quality)
+ local drop_location = type(id_num) == "string" and BZ[id_num] or nil
+
+ if drop_location then
+ drop_location = string.format(": %s", SetTextColor(CATEGORY_COLORS["location"], drop_location))
+ else
+ drop_location = ""
+ end
+ local t = AcquireTable()
+
+ t.text = string.format("%s%s%s|r%s", PADDING, hex_color, L["World Drop"], drop_location)
+ t.recipe_id = recipe_id
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandCustomData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ local t = AcquireTable()
+
+ t.text = PADDING .. SetTextColor(CATEGORY_COLORS["custom"], private.custom_list[id_num].name)
+ t.recipe_id = recipe_id
+
+ return ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ end
+
+ local function ExpandAcquireData(entry_index, entry_type, parent_entry, acquire_type, acquire_data, recipe_id, hide_location, hide_type)
+ local obtain_filters = addon.db.profile.filters.obtain
+
+ for id_num, info in pairs(acquire_data) do
+ if acquire_type == A.TRAINER and obtain_filters.trainer then
+ entry_index = ExpandTrainerData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ elseif acquire_type == A.VENDOR and (obtain_filters.vendor or obtain_filters.pvp) then
+ entry_index = ExpandVendorData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ elseif acquire_type == A.MOB_DROP and (obtain_filters.mobdrop or obtain_filters.instance or obtain_filters.raid) then
+ entry_index = ExpandMobData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ elseif acquire_type == A.QUEST and obtain_filters.quest then
+ entry_index = ExpandQuestData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ elseif acquire_type == A.SEASONAL and obtain_filters.seasonal then
+ entry_index = ExpandSeasonalData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ elseif acquire_type == A.REPUTATION then
+ for rep_level, level_info in pairs(info) do
+ for vendor_id in pairs(level_info) do
+ entry_index = ExpandReputationData(entry_index, entry_type, parent_entry, vendor_id, id_num, rep_level, recipe_id, hide_location, hide_type)
+ end
+ end
+ elseif acquire_type == A.WORLD_DROP and obtain_filters.worlddrop then
+ if not hide_type then
+ entry_index = ExpandWorldDropData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ end
+ elseif acquire_type == A.CUSTOM then
+ if not hide_type then
+ entry_index = ExpandCustomData(entry_index, entry_type, parent_entry, id_num, recipe_id, hide_location, hide_type)
+ end
+ --@alpha@
+ elseif acquire_type > A_MAX then
+ local t = AcquireTable()
+
+ t.text = "Unhandled Acquire Case - Type: " .. acquire_type
+ t.recipe_id = recipe_id
+
+ entry_index = ListFrame:InsertEntry(t, parent_entry, entry_index, entry_type, true)
+ --@end-alpha@
+ end
+ end -- for
+ return entry_index
+ end
+
+ -- This function is called when an un-expanded entry in the list has been clicked.
+ function ListFrame:ExpandEntry(entry_index, expand_mode)
+ local orig_index = entry_index
+ local current_entry = self.entries[orig_index]
+ local expand_all = expand_mode == "deep"
+ local search_box = MainPanel.search_editbox
+ local current_tab = MainPanel.tabs[MainPanel.current_tab]
+ local prof_name = private.ordered_professions[MainPanel.profession]
+
+ -- Entry_index is the position in self.entries that we want to expand. Since we are expanding the current entry, the return
+ -- value should be the index of the next button after the expansion occurs
+ entry_index = entry_index + 1
+
+ current_tab:ModifyEntry(current_entry, true)
+
+ -- This entry was generated using sorting based on Acquisition.
+ if current_entry.acquire_id then
+ local acquire_id = current_entry.acquire_id
+
+ if current_entry.type == "header" then
+ local recipe_list = private.acquire_list[acquire_id].recipes
+ local sorted_recipes = addon.sorted_recipes
+
+ private.SortRecipeList(recipe_list)
+
+ for index = 1, #sorted_recipes do
+ local spell_id = sorted_recipes[index]
+ local recipe_entry = private.recipe_list[spell_id]
+
+ if recipe_entry:HasState("VISIBLE") and search_box:MatchesRecipe(recipe_entry) then
+ local t = AcquireTable()
+ local expand = false
+ local type = "subheader"
+
+ if acquire_id == A.WORLD_DROP or acquire_id == A.CUSTOM then
+ expand = true
+ type = "entry"
+ end
+ local is_expanded = current_tab[prof_name.." expanded"][spell_id] and current_tab[prof_name.." expanded"][private.acquire_names[acquire_id]]
+
+ t.text = recipe_entry:GetDisplayName()
+ t.recipe_id = spell_id
+ t.acquire_id = acquire_id
+
+ entry_index = self:InsertEntry(t, current_entry, entry_index, type, expand or is_expanded, expand_all or is_expanded)
+ end
+ end
+ elseif current_entry.type == "subheader" then
+ for acquire_type, acquire_data in pairs(private.recipe_list[current_entry.recipe_id].acquire_data) do
+ if acquire_type == acquire_id then
+ entry_index = ExpandAcquireData(entry_index, "subentry", current_entry, acquire_type, acquire_data, current_entry.recipe_id, false, true)
+ end
+ end
+ end
+ return entry_index
+ end
+
+ -- This entry was generated using sorting based on Location.
+ if current_entry.location_id then
+ local location_id = current_entry.location_id
+
+ if current_entry.type == "header" then
+ local recipe_list = private.location_list[location_id].recipes
+ local sorted_recipes = addon.sorted_recipes
+
+ private.SortRecipeList(recipe_list)
+
+ for index = 1, #sorted_recipes do
+ local spell_id = sorted_recipes[index]
+ local recipe_entry = private.recipe_list[spell_id]
+
+ if recipe_entry:HasState("VISIBLE") and search_box:MatchesRecipe(recipe_entry) then
+ local expand = false
+ local type = "subheader"
+ local t = AcquireTable()
+
+ -- Add World Drop entries as normal entries.
+ if recipe_list[spell_id] == "world_drop" then
+ expand = true
+ type = "entry"
+ end
+ local is_expanded = current_tab[prof_name.." expanded"][spell_id] and current_tab[prof_name.." expanded"][location_id]
+
+ t.text = recipe_entry:GetDisplayName()
+ t.recipe_id = spell_id
+ t.location_id = location_id
+
+ entry_index = self:InsertEntry(t, current_entry, entry_index, type, expand or is_expanded, expand_all or is_expanded)
+ end
+ end
+ elseif current_entry.type == "subheader" then
+ local recipe_entry = private.recipe_list[current_entry.recipe_id]
+
+ -- World Drops are not handled here because they are of type "entry".
+ for acquire_type, acquire_data in pairs(recipe_entry.acquire_data) do
+ for id_num, info in pairs(acquire_data) do
+ -- Only expand an acquisition entry if it is from this location.
+ if acquire_type == A.TRAINER and private.trainer_list[id_num].location == location_id then
+ entry_index = ExpandTrainerData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true)
+ elseif acquire_type == A.VENDOR and private.vendor_list[id_num].location == location_id then
+ entry_index = ExpandVendorData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true)
+ elseif acquire_type == A.MOB_DROP and private.mob_list[id_num].location == location_id then
+ entry_index = ExpandMobData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true)
+ elseif acquire_type == A.QUEST and private.quest_list[id_num].location == location_id then
+ entry_index = ExpandQuestData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true)
+ elseif acquire_type == A.SEASONAL and private.seasonal_list[id_num].location == location_id then
+ -- Hide the acquire type for this - it will already show up in the location list as "World Events".
+ entry_index = ExpandSeasonalData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true, true)
+ elseif acquire_type == A.CUSTOM and private.custom_list[id_num].location == location_id then
+ entry_index = ExpandCustomData(entry_index, "subentry", current_entry,
+ id_num, current_entry.recipe_id, true, true)
+ elseif acquire_type == A.REPUTATION then
+ for rep_level, level_info in pairs(info) do
+ for vendor_id in pairs(level_info) do
+ if private.vendor_list[vendor_id].location == location_id then
+ entry_index = ExpandReputationData(entry_index, "subentry", current_entry,
+ vendor_id, id_num, rep_level, current_entry.recipe_id, true)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return entry_index
+ end
+
+ -- Normal entry - expand all acquire types.
+ local recipe_id = self.entries[orig_index].recipe_id
+
+ for acquire_type, acquire_data in pairs(private.recipe_list[recipe_id].acquire_data) do
+ entry_index = ExpandAcquireData(entry_index, "entry", current_entry, acquire_type, acquire_data, recipe_id)
+ end
+ return entry_index
+ end
+end -- InitializeListFrame()
+
+-------------------------------------------------------------------------------
+-- Tooltip functions and data.
+-------------------------------------------------------------------------------
+spell_tip = CreateFrame("GameTooltip", "AckisRecipeList_SpellTooltip", UIParent, "GameTooltipTemplate")
+
+-- Font Objects needed for acquire_tip
+local narrowFont
+local normalFont
+
+do
+ -- Fallback in case the user doesn't have LSM-3.0 installed
+ if not LibStub:GetLibrary("LibSharedMedia-3.0", true) then
+
+ local locale = GetLocale()
+ -- Fix for font issues on koKR
+ if locale == "koKR" then
+ narrowFont = "Fonts\\2002.TTF"
+ normalFont = "Fonts\\2002.TTF"
+ else
+ narrowFont = "Fonts\\ARIALN.TTF"
+ normalFont = "Fonts\\FRIZQT__.TTF"
+ end
+ else
+ -- Register LSM 3.0
+ local LSM3 = LibStub("LibSharedMedia-3.0")
+
+ narrowFont = LSM3:Fetch(LSM3.MediaType.FONT, "Arial Narrow")
+ normalFont = LSM3:Fetch(LSM3.MediaType.FONT, "Friz Quadrata TT")
+ end
+ local narrowFontObj = CreateFont(MODNAME.."narrowFontObj")
+ local normalFontObj = CreateFont(MODNAME.."normalFontObj")
+
+ -- I want to do a bit more comprehensive tooltip processing. Things like changing font sizes,
+ -- adding padding to the left hand side, and using better color handling. So... this function
+ -- will do that for me.
+ local function ttAdd(
+ leftPad, -- number of times to pad two spaces on left side
+ textSize, -- add to or subtract from addon.db.profile.tooltip.acquire_fontsize to get fontsize
+ narrow, -- if 1, use ARIALN instead of FRITZQ
+ str1, -- left-hand string
+ hexcolor1, -- hex color code for left-hand side
+ str2, -- if present, this is the right-hand string
+ hexcolor2) -- if present, hex color code for right-hand side
+
+ -- are we changing fontsize or narrow?
+ local fontSize
+
+ if narrow or textSize ~= 0 then
+ local font = narrow and narrowFont or normalFont
+ local fontObj = narrow and narrowFontObj or normalFontObj
+
+ fontSize = addon.db.profile.tooltip.acquire_fontsize + textSize
+
+ fontObj:SetFont(font, fontSize)
+ acquire_tip:SetFont(fontObj)
+ end
+
+ -- Add in our left hand padding
+ local loopPad = leftPad
+ local leftStr = str1
+
+ while loopPad > 0 do
+ leftStr = " " .. leftStr
+ loopPad = loopPad - 1
+ end
+ -- Set maximum width to match fontSize to maintain uniform tooltip size. -Torhal
+ local width = math.ceil(fontSize * 37.5)
+ local line = acquire_tip:AddLine()
+
+ if str2 then
+ width = width / 2
+
+ acquire_tip:SetCell(line, 1, "|cff"..hexcolor1..leftStr.."|r", "LEFT", nil, nil, 0, 0, width, width)
+ acquire_tip:SetCell(line, 2, "|cff"..hexcolor2..str2.."|r", "RIGHT", nil, nil, 0, 0, width, width)
+ else
+ acquire_tip:SetCell(line, 1, "|cff"..hexcolor1..leftStr.."|r", nil, "LEFT", 2, nil, 0, 0, width, width)
+ end
+ end
+
+ local function SetSpellTooltip(owner, loc, link)
+ spell_tip:SetOwner(owner, "ANCHOR_NONE")
+ spell_tip:ClearAllPoints()
+
+ if loc == "Top" then
+ spell_tip:SetPoint("BOTTOMLEFT", owner, "TOPLEFT")
+ elseif loc == "Bottom" then
+ spell_tip:SetPoint("TOPLEFT", owner, "BOTTOMLEFT")
+ elseif loc == "Left" then
+ spell_tip:SetPoint("TOPRIGHT", owner, "TOPLEFT")
+ elseif loc == "Right" then
+ spell_tip:SetPoint("TOPLEFT", owner, "TOPRIGHT")
+ end
+
+ -- Add TipTac Support
+ if _G.TipTac and _G.TipTac.AddModifiedTip and not spell_tip.tiptac then
+ _G.TipTac:AddModifiedTip(spell_tip)
+ spell_tip.tiptac = true
+ end
+
+ -- Set the spell tooltip's scale, and copy its other values from GameTooltip so AddOns which modify it will work.
+ spell_tip:SetBackdrop(GameTooltip:GetBackdrop())
+ spell_tip:SetBackdropColor(GameTooltip:GetBackdropColor())
+ spell_tip:SetBackdropBorderColor(GameTooltip:GetBackdropBorderColor())
+ spell_tip:SetScale(addon.db.profile.tooltip.scale)
+ spell_tip:SetClampedToScreen(true)
+ spell_tip:SetHyperlink(link)
+ spell_tip:Show()
+ end
+
+ local function GetTipFactionInfo(comp_faction)
+ local display_tip
+ local color
+
+ if comp_faction == FACTION_NEUTRAL then
+ color = private.reputation_colors["neutral"]
+ display_tip = true
+ elseif comp_faction == BFAC[Player.faction] then
+ color = private.reputation_colors["exalted"]
+ display_tip = true
+ else
+ color = private.reputation_colors["hated"]
+ display_tip = addon.db.profile.filters.general.faction
+ end
+ return display_tip, color
+ end
+
+ -------------------------------------------------------------------------------
+ -- Functions for adding individual acquire type data to the tooltip.
+ -------------------------------------------------------------------------------
+ local function Tooltip_AddTrainer(id_num, location, addline_func)
+ local trainer = private.trainer_list[id_num]
+
+ if location and trainer.location ~= location then
+ return
+ end
+ local display_tip, name_color = GetTipFactionInfo(trainer.faction)
+
+ if display_tip then
+ local coord_text = ""
+
+ if trainer.coord_x ~= 0 and trainer.coord_y ~= 0 then
+ coord_text = "(" .. trainer.coord_x .. ", " .. trainer.coord_y .. ")"
+ end
+ addline_func(0, -2, false, L["Trainer"], CATEGORY_COLORS["trainer"], trainer.name, name_color)
+ addline_func(1, -2, true, trainer.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
+ end
+ end
+
+ local function Tooltip_AddVendor(recipe_id, id_num, location, addline_func)
+ local vendor = private.vendor_list[id_num]
+
+ if location and vendor.location ~= location then
+ return
+ end
+ local type_color = CATEGORY_COLORS["vendor"]
+ local display_tip, name_color = GetTipFactionInfo(vendor.faction)
+
+ if display_tip then
+ local coord_text = ""
+
+ if vendor.coord_x ~= 0 and vendor.coord_y ~= 0 then
+ coord_text = "(" .. vendor.coord_x .. ", " .. vendor.coord_y .. ")"
+ end
+ addline_func(0, -1, false, L["Vendor"], type_color, vendor.name, name_color)
+ addline_func(1, -2, true, vendor.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
+
+ local quantity = vendor.item_list[recipe_id]
+
+ if type(quantity) == "number" then
+ addline_func(2, -2, true, L["LIMITED_SUPPLY"], type_color, string.format("(%d)", quantity), BASIC_COLORS["white"])
+ end
+ end
+ end
+
+ local function Tooltip_AddMobDrop(id_num, location, addline_func)
+ local mob = private.mob_list[id_num]
+
+ if location and mob.location ~= location then
+ return
+ end
+ local coord_text = ""
+
+ if mob.coord_x ~= 0 and mob.coord_y ~= 0 then
+ coord_text = "(" .. mob.coord_x .. ", " .. mob.coord_y .. ")"
+ end
+ addline_func(0, -1, false, L["Mob Drop"], CATEGORY_COLORS["mobdrop"], mob.name, private.reputation_colors["hostile"])
+ addline_func(1, -2, true, mob.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
+ end
+
+ local function Tooltip_AddQuest(id_num, location, addline_func)
+ local quest = private.quest_list[id_num]
+
+ if location and quest.location ~= location then
+ return
+ end
+ local type_color = CATEGORY_COLORS["quest"]
+ local display_tip, name_color = GetTipFactionInfo(quest.faction)
+
+ if display_tip then
+ local coord_text = ""
+
+ if quest.coord_x ~= 0 and quest.coord_y ~= 0 then
+ coord_text = "(" .. quest.coord_x .. ", " .. quest.coord_y .. ")"
+ end
+ addline_func(0, -1, false, L["Quest"], type_color, private.quest_names[id_num], name_color)
+ addline_func(1, -2, true, quest.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
+ end
+ end
+
+ local function Tooltip_AddRepVendor(id_num, location, rep_id, rep_level, vendor_id, addline_func)
+ local rep_vendor = private.vendor_list[vendor_id]
+
+ if location and rep_vendor.location ~= location then
+ return
+ end
+ local display_tip, name_color = GetTipFactionInfo(rep_vendor.faction)
+
+ if display_tip then
+ local rep_color = private.reputation_colors
+ local rep_str = ""
+ local type_color
+
+ if rep_level == 0 then
+ rep_str = FACTION_NEUTRAL
+ type_color = rep_color["neutral"]
+ elseif rep_level == 1 then
+ rep_str = BFAC["Friendly"]
+ type_color = rep_color["friendly"]
+ elseif rep_level == 2 then
+ rep_str = BFAC["Honored"]
+ type_color = rep_color["honored"]
+ elseif rep_level == 3 then
+ rep_str = BFAC["Revered"]
+ type_color = rep_color["revered"]
+ else
+ rep_str = BFAC["Exalted"]
+ type_color = rep_color["exalted"]
+ end
+ addline_func(0, -1, false, _G.REPUTATION, CATEGORY_COLORS["reputation"], private.reputation_list[id_num].name, CATEGORY_COLORS["repname"])
+ addline_func(1, -2, false, rep_str, type_color, rep_vendor.name, name_color)
+
+ local coord_text = ""
+
+ if rep_vendor.coord_x ~= 0 and rep_vendor.coord_y ~= 0 then
+ coord_text = "(" .. rep_vendor.coord_x .. ", " .. rep_vendor.coord_y .. ")"
+ end
+ addline_func(2, -2, true, rep_vendor.location, CATEGORY_COLORS["location"], coord_text, CATEGORY_COLORS["coords"])
+ end
+ end
+
+ local function Tooltip_AddWorldDrop(recipe_id, id_num, location, addline_func)
+ local drop_location = type(id_num) == "string" and BZ[id_num] or nil
+
+ if location and drop_location ~= location then
+ return
+ end
+ local item_id = private.spell_to_recipe_map[recipe_id]
+ local _, item_level
+
+ if item_id then
+ _, _, _, item_level = GetItemInfo(item_id)
+ end
+ local _, _, _, quality_color = GetItemQualityColor(private.recipe_list[recipe_id].quality)
+ local type_color = string.gsub(quality_color, "|cff", "")
+
+ if type(id_num) == "string" then
+ local location_text = item_level and string.format("%s (%d - %d)", drop_location, item_level - 5, item_level + 5) or drop_location
+
+ addline_func(0, -1, false, L["World Drop"], type_color, location_text, CATEGORY_COLORS["location"])
+ else
+ local location_text = item_level and string.format("%s (%d - %d)", _G.UNKNOWN, item_level - 5, item_level + 5) or _G.UNKNOWN
+
+ addline_func(0, -1, false, L["World Drop"], type_color, location_text, CATEGORY_COLORS["location"])
+ end
+ end
+
+ -------------------------------------------------------------------------------
+ -- Public API function for displaying a recipe's acquire data.
+ -- * The addline_func paramater must be a function which accepts the same
+ -- * arguments as ARL's ttAdd function.
+ -------------------------------------------------------------------------------
+ function addon:DisplayAcquireData(recipe_id, acquire_id, location, addline_func)
+ local recipe = private.recipe_list[recipe_id]
+
+ if not recipe then
+ return
+ end
+
+ for acquire_type, acquire_data in pairs(recipe.acquire_data) do
+ local can_display = (not acquire_id or acquire_type == acquire_id)
+
+ if can_display then
+ for id_num, info in pairs(acquire_data) do
+ if acquire_type == A.TRAINER then
+ Tooltip_AddTrainer(id_num, location, addline_func)
+ elseif acquire_type == A.VENDOR then
+ Tooltip_AddVendor(recipe_id, id_num, location, addline_func)
+ elseif acquire_type == A.MOB_DROP then
+ Tooltip_AddMobDrop(id_num, location, addline_func)
+ elseif acquire_type == A.QUEST then
+ Tooltip_AddQuest(id_num, location, addline_func)
+ elseif acquire_type == A.SEASONAL then
+ color_1 = CATEGORY_COLORS["seasonal"]
+ addline_func(0, -1, 0, private.acquire_names[A.SEASONAL], color_1, private.seasonal_list[id_num].name, color_1)
+ elseif acquire_type == A.REPUTATION then
+ for rep_level, level_info in pairs(info) do
+ for vendor_id in pairs(level_info) do
+ Tooltip_AddRepVendor(id_num, location, rep_id, rep_level, vendor_id, addline_func)
+ end
+ end
+ elseif acquire_type == A.WORLD_DROP then
+ Tooltip_AddWorldDrop(recipe_id, id_num, location, addline_func)
+ elseif acquire_type == A.CUSTOM then
+ addline_func(0, -1, false, private.custom_list[id_num].name, CATEGORY_COLORS["custom"])
+ --@alpha@
+ elseif can_display then
+ -- Unhandled
+ addline_func(0, -1, 0, L["Unhandled Recipe"], BASIC_COLORS["normal"])
+ --@end-alpha@
+ end
+ end -- for id_num
+ end -- if can_display
+ end -- for acquire_type
+ end
+
+ -------------------------------------------------------------------------------
+ -- Main tooltip-generating function.
+ -------------------------------------------------------------------------------
+ local BINDING_FLAGS = {
+ [COMMON_FLAGS_1.IBOE] = L["BOEFilter"],
+ [COMMON_FLAGS_1.IBOP] = L["BOPFilter"],
+ [COMMON_FLAGS_1.IBOA] = L["BOAFilter"],
+ [COMMON_FLAGS_1.RBOE] = L["RecipeBOEFilter"],
+ [COMMON_FLAGS_1.RBOP] = L["RecipeBOPFilter"],
+ [COMMON_FLAGS_1.RBOA] = L["RecipeBOAFilter"]
+ }
+
+ function ListItem_ShowTooltip(owner, list_entry)
+ if not list_entry then
+ return
+ end
+ local recipe_id = list_entry.recipe_id
+ local recipe = private.recipe_list[recipe_id]
+
+ if not recipe then
+ return
+ end
+ local spell_tip_anchor = addon.db.profile.spelltooltiplocation
+ local acquire_tip_anchor = addon.db.profile.acquiretooltiplocation
+ local spell_link = GetSpellLink(recipe.spell_id)
+ local MainPanel = addon.Frame
+
+ if acquire_tip_anchor == _G.OFF then
+ QTip:Release(acquire_tip)
+
+ -- If we have the spell link tooltip, anchor it to MainPanel instead so it shows
+ if spell_tip_anchor ~= _G.OFF and spell_link then
+ SetSpellTooltip(MainPanel, spell_tip_anchor, spell_link)
+ else
+ spell_tip:Hide()
+ end
+ return
+ end
+ acquire_tip = QTip:Acquire(MODNAME.." Tooltip", 2, "LEFT", "LEFT")
+ acquire_tip:ClearAllPoints()
+
+ if acquire_tip_anchor == "Right" then
+ acquire_tip:SetPoint("TOPLEFT", MainPanel, "TOPRIGHT", MainPanel.is_expanded and -90 or -35, 0)
+ elseif acquire_tip_anchor == "Left" then
+ acquire_tip:SetPoint("TOPRIGHT", MainPanel, "TOPLEFT")
+ elseif acquire_tip_anchor == "Top" then
+ acquire_tip:SetPoint("BOTTOMLEFT", MainPanel, "TOPLEFT")
+ elseif acquire_tip_anchor == "Bottom" then
+ acquire_tip:SetPoint("TOPLEFT", MainPanel, "BOTTOMLEFT", 0, 55)
+ elseif acquire_tip_anchor == "Mouse" then
+ local x, y = GetCursorPosition()
+ local uiscale = UIParent:GetEffectiveScale()
+
+ acquire_tip:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x / uiscale, y / uiscale)
+ end
+ acquire_tip:SetClampedToScreen(true)
+
+ if _G.TipTac and _G.TipTac.AddModifiedTip then
+ -- Pass true as second parameter because hooking OnHide causes C stack overflows -Torhal
+ _G.TipTac:AddModifiedTip(acquire_tip, true)
+ end
+ local _, _, _, quality_color = GetItemQualityColor(recipe.quality)
+
+ acquire_tip:Clear()
+ acquire_tip:SetScale(addon.db.profile.tooltip.scale)
+ acquire_tip:AddHeader()
+ acquire_tip:SetCell(1, 1, quality_color..recipe.name, "CENTER", 2)
+
+ -- check if the recipe is excluded
+ if addon.db.profile.exclusionlist[recipe_id] then
+ ttAdd(0, -1, true, L["RECIPE_EXCLUDED"], "ff0000")
+ end
+
+ -- Add in skill level requirement, colored correctly
+ local color_1 = BASIC_COLORS["normal"]
+ local color_2
+
+ local skill_level = Player["ProfessionLevel"]
+ local recipe_level = recipe.skill_level
+ local optimal_level = recipe.optimal_level
+ local medium_level = recipe.medium_level
+ local easy_level = recipe.easy_level
+ local trivial_level = recipe.trivial_level
+ local difficulty = private.difficulty_colors
+
+ if recipe_level > skill_level then
+ color_2 = difficulty["impossible"]
+ elseif skill_level >= trivial_level then
+ color_2 = difficulty["trivial"]
+ elseif skill_level >= easy_level then
+ color_2 = difficulty["easy"]
+ elseif skill_level >= medium_level then
+ color_2 = difficulty["medium"]
+ elseif skill_level >= optimal_level then
+ color_2 = difficulty["optimal"]
+ else
+ color_2 = difficulty["trivial"]
+ end
+ ttAdd(0, -1, false, string.format("%s:", _G.SKILL_LEVEL), color_1, recipe.skill_level, color_2)
+
+ -- Binding info
+ acquire_tip:AddSeparator()
+ color_1 = BASIC_COLORS["normal"]
+
+ for flag, label in pairs(BINDING_FLAGS) do
+ if bit.band(recipe.flags.common1, flag) == flag then
+ ttAdd(0, -1, true, label, color_1)
+ end
+ end
+ acquire_tip:AddSeparator()
+
+ if recipe.specialty then
+ local spec = recipe.specialty
+ local spec_name = GetSpellInfo(spec)
+ local known = (spec == Player["Specialty"])
+
+ ttAdd(0, -1, false, string.format(_G.ITEM_REQ_SKILL, spec_name), known and BASIC_COLORS["white"] or difficulty["impossible"])
+ acquire_tip:AddSeparator()
+ end
+
+ ttAdd(0, -1, false, L["Obtained From"] .. " : ", BASIC_COLORS["normal"])
+
+ local acquire_id = list_entry.acquire_id
+ local location = list_entry.location_id
+
+ addon:DisplayAcquireData(recipe_id, acquire_id, location, ttAdd)
+
+ if not addon.db.profile.hide_tooltip_hint then
+ -- Give the tooltip hint a unique color.
+ color_1 = "c9c781"
+
+ acquire_tip:AddSeparator()
+ acquire_tip:AddSeparator()
+
+ ttAdd(0, -1, 0, L["ALT_CLICK"], color_1)
+ ttAdd(0, -1, 0, L["CTRL_CLICK"], color_1)
+ ttAdd(0, -1, 0, L["SHIFT_CLICK"], color_1)
+
+ if acquire_id ~= A.WORLD_DROP and acquire_id ~= A.CUSTOM and (_G.TomTom or _G.Cartographer_Waypoints) and (addon.db.profile.worldmap or addon.db.profile.minimap) then
+ ttAdd(0, -1, 0, L["CTRL_SHIFT_CLICK"], color_1)
+ end
+ end
+ acquire_tip:Show()
+
+ -- If we have the spell link tooltip, link it to the acquire tooltip.
+ if spell_tip_anchor ~= _G.OFF and spell_link then
+ SetSpellTooltip(acquire_tip, spell_tip_anchor, spell_link)
+ else
+ spell_tip:Hide()
+ end
+ end
+end -- do
diff --git a/interface.xml b/interface.xml
index 84fe4d4..3dd469a 100644
--- a/interface.xml
+++ b/interface.xml
@@ -4,5 +4,6 @@
<Include file="Interface\Common.lua"/>
<Include file="Interface\Tabs.lua"/>
+<Include file="Interface\List.lua"/>
</Ui>