Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 151 additions & 3 deletions EUI_QoL.lua
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ qolFrame:SetScript("OnEvent", function(self)
local function GetApplicantScore(applicantID)
if not C_LFGList or not C_LFGList.GetApplicantMemberInfo then return nil end
local _, _, _, _, _, _, _, _, _, _, _, dungeonScore = C_LFGList.GetApplicantMemberInfo(applicantID, 1)
if dungeonScore == nil then return nil end
if issecretvalue and issecretvalue(dungeonScore) then return nil end
if type(dungeonScore) ~= "number" then return nil end
return dungeonScore
end
Expand All @@ -754,9 +756,9 @@ qolFrame:SetScript("OnEvent", function(self)
table.sort(applicants, function(a, b)
local sa = scores[a]
local sb = scores[b]
if sa ~= nil and sb ~= nil and sa ~= sb then return sa > sb end
if sa ~= nil and sb == nil then return true end
if sa == nil and sb ~= nil then return false end
if sa and sb and sa ~= sb then return sa > sb end
if sa and not sb then return true end
if not sa and sb then return false end
return (originalOrder[a] or 0) < (originalOrder[b] or 0)
end)
end)
Expand Down Expand Up @@ -960,6 +962,152 @@ qolFrame:SetScript("OnEvent", function(self)
return false
end

---------------------------------------------------------------------------
-- Bag Item Level Labels
-- Draws a small item-level number on every equippable item in the bag.
-- Setting: EllesmereUIDB.bagIlvlEnabled (default: true)
---------------------------------------------------------------------------
do
-- Items worth showing a level on: anything that occupies a gear slot.
-- Bags, tabards, ammo pouches and cosmetics are intentionally excluded.
local function IsGearSlot(equipSlot, classID, subclassID)
if not equipSlot or equipSlot == "" then return false end
if equipSlot == "INVTYPE_NON_EQUIP_IGNORE" then return false end
if equipSlot == "INVTYPE_TABARD" then return false end
if equipSlot == "INVTYPE_BAG" then return false end
if equipSlot == "INVTYPE_QUIVER" then return false end
-- classID 4 = Armor, subclassID 5 = Cosmetic
if classID == 4 and subclassID == 5 then return false end
return true
end

-- Pixel nudge per corner so the number sits just inside the icon edge.
local CORNER_OFFSET = {
TOPLEFT = { 1, -1 },
TOPRIGHT = { -1, -1 },
BOTTOMLEFT = { 1, 1 },
BOTTOMRIGHT = { -1, 1 },
}

local function GetCorner()
return (EllesmereUIDB and EllesmereUIDB.bagIlvlAnchor) or "BOTTOMLEFT"
end

local function GetSize()
return (EllesmereUIDB and EllesmereUIDB.bagIlvlFontSize) or 11
end

local function GetFace()
return (EllesmereUI and EllesmereUI.GetFont and EllesmereUI.GetFont())
or STANDARD_TEXT_FONT
end

local function IsActive()
return not (EllesmereUIDB and EllesmereUIDB.bagIlvlEnabled == false)
end

-- Retrieve or create the FontString attached to a button.
local function GetOrCreateTag(btn)
if btn._euiIlvlTag then return btn._euiIlvlTag end
-- Use OVERLAY so the text renders above the item icon texture
-- but stays below Blizzard's own search-dimming overlay.
local tag = btn:CreateFontString(nil, "OVERLAY")
tag:SetFont(GetFace(), GetSize(), "THINOUTLINE")
tag:SetShadowOffset(1, -1)
tag:SetShadowColor(0, 0, 0, 0.9)
btn._euiIlvlTag = tag
return tag
end

local function PaintButton(btn, bag, slot)
if not btn then return end
local tag = GetOrCreateTag(btn)

if not IsActive() then tag:Hide(); return end

local link = C_Container.GetContainerItemLink(bag, slot)
if not link then tag:Hide(); return end

local _, _, quality, _, _, classID, subclassID, _, equipSlot =
C_Item.GetItemInfo(link)

if not IsGearSlot(equipSlot, classID, subclassID) then
tag:Hide(); return
end

-- GetCurrentItemLevel via ItemLocation is the only reliable way
-- to get the actual equipped/upgraded level rather than base level.
local loc = ItemLocation:CreateFromBagAndSlot(bag, slot)
local lvl = loc and C_Item.GetCurrentItemLevel(loc)
if not lvl or lvl <= 0 then tag:Hide(); return end

-- Refresh font in case the user changed size in settings
tag:SetFont(GetFace(), GetSize(), "THINOUTLINE")

local corner = GetCorner()
local off = CORNER_OFFSET[corner] or CORNER_OFFSET.BOTTOMLEFT
tag:ClearAllPoints()
tag:SetPoint(corner, btn, corner, off[1], off[2])

-- Colour by quality; grey fallback for unknown quality
if quality and quality >= 0 then
local r, g, b = C_Item.GetItemQualityColor(quality)
tag:SetTextColor(r, g, b, 1)
else
tag:SetTextColor(0.8, 0.8, 0.8, 1)
end

tag:SetText(lvl)
tag:Show()
end

local function ScanOpenBags()
if ContainerFrameCombinedBags and ContainerFrameCombinedBags:IsShown() then
for _, btn in ContainerFrameCombinedBags:EnumerateValidItems() do
PaintButton(btn, btn:GetBagID(), btn:GetID())
end
end
for _, frame in ipairs((ContainerFrameContainer and
ContainerFrameContainer.ContainerFrames) or {}) do
if frame:IsShown() then
for _, btn in frame:EnumerateValidItems() do
PaintButton(btn, btn:GetBagID(), btn:GetID())
end
end
end
end

-- Event-driven refresh
local watchFrame = CreateFrame("Frame")
watchFrame:RegisterEvent("BAG_UPDATE_DELAYED")
watchFrame:RegisterEvent("ITEM_UPGRADE_MASTER_SET_ITEM")
watchFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
watchFrame:RegisterEvent("BAG_OPEN")
watchFrame:SetScript("OnEvent", function(_, event)
if event == "PLAYER_ENTERING_WORLD" then
C_Timer.After(2, ScanOpenBags)
else
ScanOpenBags()
end
end)

-- Refresh when any individual bag frame becomes visible
for _, frame in ipairs((ContainerFrameContainer and
ContainerFrameContainer.ContainerFrames) or {}) do
frame:HookScript("OnShow", function()
C_Timer.After(0.1, ScanOpenBags)
end)
end
if ContainerFrameCombinedBags then
ContainerFrameCombinedBags:HookScript("OnShow", function()
C_Timer.After(0.1, ScanOpenBags)
end)
end

-- Expose a refresh handle for the options panel
EllesmereUI._refreshBagIlvl = ScanOpenBags
end

local resetAnnounceFrame = CreateFrame("Frame")
resetAnnounceFrame:RegisterEvent("CHAT_MSG_SYSTEM")
resetAnnounceFrame:SetScript("OnEvent", function(self, event, msg)
Expand Down
134 changes: 132 additions & 2 deletions EUI__General_Options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1616,7 +1616,7 @@ initFrame:SetScript("OnEvent", function(self)
local function CreateFPSCounter()
if fpsFrame then return end
local FONT = EllesmereUI.GetFontPath("extras")
local FONT_SIZE = 12
local FONT_SIZE = (EllesmereUIDB and EllesmereUIDB.fpsTextSize) or 12
local LABEL_SIZE = FONT_SIZE - 2
local SHADOW_X, SHADOW_Y = 1, -1
fpsFrame = CreateFrame("Frame", "EUI_FPSCounter", UIParent)
Expand Down Expand Up @@ -1742,6 +1742,16 @@ initFrame:SetScript("OnEvent", function(self)
local shouldShow = EllesmereUIDB and EllesmereUIDB.showFPS
if shouldShow then
CreateFPSCounter()
-- Re-apply text size from DB
local sz = (EllesmereUIDB and EllesmereUIDB.fpsTextSize) or 12
local lblSz = sz - 2
local fp = EllesmereUI.GetFontPath("extras")
local outF = EllesmereUI.GetFontOutlineFlag()
if fpsFrame._text then fpsFrame._text:SetFont(fp, sz, outF) end
if fpsFrame._textWorld then fpsFrame._textWorld:SetFont(fp, sz, outF) end
if fpsFrame._textLocal then fpsFrame._textLocal:SetFont(fp, sz, outF) end
if fpsFrame._lblWorld then fpsFrame._lblWorld:SetFont(fp, lblSz, outF) end
if fpsFrame._lblLocal then fpsFrame._lblLocal:SetFont(fp, lblSz, outF) end
-- Apply saved position and scale
local pos = EllesmereUIDB and EllesmereUIDB.fpsPos
if pos and pos.point then
Expand Down Expand Up @@ -1918,7 +1928,8 @@ initFrame:SetScript("OnEvent", function(self)

-- Font -- pull from the global "extras" font key
local fontPath = EllesmereUI.GetFontPath("extras")
fs:SetFont(fontPath, 18, EllesmereUI.GetFontOutlineFlag())
local durSz = (EllesmereUIDB and EllesmereUIDB.durWarnTextSize) or 30
fs:SetFont(fontPath, durSz, EllesmereUI.GetFontOutlineFlag())

-- Color
local c = EllesmereUIDB and EllesmereUIDB.durWarnColor
Expand Down Expand Up @@ -1962,6 +1973,7 @@ initFrame:SetScript("OnEvent", function(self)
CreateDurabilityWarning()
durWarnOverlay._applySettings()
end
EllesmereUI._durWarnApplySettings = EllesmereUI._applyDurWarn

-- Preview: show durability warning at its configured position
EllesmereUI._durWarnPreview = function()
Expand Down Expand Up @@ -2465,6 +2477,16 @@ initFrame:SetScript("OnEvent", function(self)
local _, fpsCogShow = EllesmereUI.BuildCogPopup({
title = "FPS Counter Settings",
rows = {
{ type="slider", label="Text Size",
min=8, max=24, step=1,
get=function()
return (EllesmereUIDB and EllesmereUIDB.fpsTextSize) or 12
end,
set=function(v)
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.fpsTextSize = v
if EllesmereUI._applyFPSCounter then EllesmereUI._applyFPSCounter() end
end },
{ type="toggle", label="Show Local MS",
get=function()
if not EllesmereUIDB or EllesmereUIDB.fpsShowLocalMS == nil then return true end
Expand Down Expand Up @@ -2729,6 +2751,16 @@ initFrame:SetScript("OnEvent", function(self)
local _, durCogShow = EllesmereUI.BuildCogPopup({
title = "Durability Settings",
rows = {
{ type="slider", label="Text Size",
min=10, max=50, step=1,
get=function()
return (EllesmereUIDB and EllesmereUIDB.durWarnTextSize) or 30
end,
set=function(v)
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.durWarnTextSize = v
if EllesmereUI._durWarnApplySettings then EllesmereUI._durWarnApplySettings() end
end },
{ type="slider", label="Y-Offset",
min=-600, max=600, step=1,
get=function()
Expand Down Expand Up @@ -3342,6 +3374,104 @@ initFrame:SetScript("OnEvent", function(self)
end }
); y = y - h

---------------------------------------------------------------------------
-- BAGS
---------------------------------------------------------------------------
_, h = W:SectionHeader(parent, "BAGS", y); y = y - h

local ilvlRow
ilvlRow, h = W:DualRow(parent, y,
{ type="toggle", text="Show Item Level in Bags",
tooltip="Displays the current item level as a small label on each equippable item in your bags. The label colour matches the item quality.",
getValue=function()
return not (EllesmereUIDB and EllesmereUIDB.bagIlvlEnabled == false)
end,
setValue=function(v)
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.bagIlvlEnabled = v and true or false
if EllesmereUI._refreshBagIlvl then EllesmereUI._refreshBagIlvl() end
EllesmereUI:RefreshPage()
end },
{ type="label", text="" }
); y = y - h

-- Cog on the item-level toggle (position & font-size sub-settings)
do
local leftRgn = ilvlRow._leftRegion
local function ilvlOff()
return EllesmereUIDB and EllesmereUIDB.bagIlvlEnabled == false
end

-- Pre-declare the values table as upvalue so the CogPopup closure
-- captures a fully-initialised table (inline literals can arrive nil
-- if the popup is created lazily before the table is resolved).
local posValues = {
TOPLEFT = "Top Left",
TOPRIGHT = "Top Right",
BOTTOMLEFT = "Bottom Left",
BOTTOMRIGHT= "Bottom Right",
}
local posOrder = { "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT" }

local _, ilvlCogShow = EllesmereUI.BuildCogPopup({
title = "Bag Item Level Settings",
rows = {
{ type="dropdown",
label="Position",
values=posValues,
order=posOrder,
get=function()
return (EllesmereUIDB and EllesmereUIDB.bagIlvlAnchor) or "BOTTOMLEFT"
end,
set=function(v)
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.bagIlvlAnchor = v
if EllesmereUI._refreshBagIlvl then EllesmereUI._refreshBagIlvl() end
end },
{ type="slider",
label="Font Size",
min=6, max=20, step=1,
get=function()
return (EllesmereUIDB and EllesmereUIDB.bagIlvlFontSize) or 11
end,
set=function(v)
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.bagIlvlFontSize = v
if EllesmereUI._refreshBagIlvl then EllesmereUI._refreshBagIlvl() end
end },
},
})

local ilvlCogBtn = CreateFrame("Button", nil, leftRgn)
ilvlCogBtn:SetSize(26, 26)
ilvlCogBtn:SetPoint("RIGHT", leftRgn._lastInline or leftRgn._control, "LEFT", -9, 0)
leftRgn._lastInline = ilvlCogBtn
ilvlCogBtn:SetFrameLevel(leftRgn:GetFrameLevel() + 5)
ilvlCogBtn:SetAlpha(ilvlOff() and 0.15 or 0.4)
local ilvlCogTex = ilvlCogBtn:CreateTexture(nil, "OVERLAY")
ilvlCogTex:SetAllPoints()
ilvlCogTex:SetTexture(EllesmereUI.COGS_ICON)
ilvlCogBtn:SetScript("OnEnter", function(self) self:SetAlpha(0.7) end)
ilvlCogBtn:SetScript("OnLeave", function(self) self:SetAlpha(ilvlOff() and 0.15 or 0.4) end)
ilvlCogBtn:SetScript("OnClick", function(self) ilvlCogShow(self) end)

local ilvlCogBlock = CreateFrame("Frame", nil, ilvlCogBtn)
ilvlCogBlock:SetAllPoints()
ilvlCogBlock:SetFrameLevel(ilvlCogBtn:GetFrameLevel() + 10)
ilvlCogBlock:EnableMouse(true)
ilvlCogBlock:SetScript("OnEnter", function()
EllesmereUI.ShowWidgetTooltip(ilvlCogBtn, EllesmereUI.DisabledTooltip("Show Item Level in Bags"))
end)
ilvlCogBlock:SetScript("OnLeave", function() EllesmereUI.HideWidgetTooltip() end)

EllesmereUI.RegisterWidgetRefresh(function()
local off = ilvlOff()
ilvlCogBtn:SetAlpha(off and 0.15 or 0.4)
if off then ilvlCogBlock:Show() else ilvlCogBlock:Hide() end
end)
if ilvlOff() then ilvlCogBlock:Show() else ilvlCogBlock:Hide() end
end

_, h = W:Spacer(parent, y, 20); y = y - h
return math.abs(y)
end
Expand Down