diff --git a/Config.lua b/Config.lua index 025eeab..8a51ed9 100644 --- a/Config.lua +++ b/Config.lua @@ -5,6 +5,8 @@ F.Config = { showAtMaxLevel = false, showIncompleteQuestBar = true, questTrackingEnabled = true, + showTicks = true, + tickOpacity = 0.35, -- Master visibility toggle (can be flipped with /nxp toggle) enabled = true, diff --git a/Options.lua b/Options.lua index 84656bc..55ef106 100644 --- a/Options.lua +++ b/Options.lua @@ -15,6 +15,8 @@ local questRelatedKeys = { colorQuestComplete = true, } +local TICK_OPACITY_KEY = "tickOpacity" + local function SetOption(key, value) if F.InitDB then F.InitDB() end if not F.DB then return end @@ -49,7 +51,18 @@ end local function SetNumericOption(key, value) if F.InitDB then F.InitDB() end if not F.DB then return end - F.DB[key] = value + if key == "barWidth" then + local width = tonumber(value) or 0 + local scale = UIParent and UIParent:GetEffectiveScale() or 1 + local stepPixels = math.floor(((width / 20) * scale) + 0.5) + local snapped = (stepPixels / scale) * 20 + if snapped < 200 then snapped = 200 end + F.DB[key] = snapped + elseif key == TICK_OPACITY_KEY then + F.DB[key] = (tonumber(value) or 0) / 100 + else + F.DB[key] = value + end if F.UpdateUI then F.UpdateUI() end end @@ -213,6 +226,9 @@ function F.Options.Refresh() local value = F.DB[key] if value == nil then value = defaults[key] end if value == nil then value = 0 end + if key == TICK_OPACITY_KEY then + value = (tonumber(value) or 0) * 100 + end control.widget._updating = true control.widget:SetValue(tonumber(value) or 0) control.widget._updating = false @@ -281,6 +297,8 @@ function F.Options.Create() y = CreateCheckbox(content, "questTrackingEnabled", "Enable quest tracking", y) y = CreateCheckbox(content, "trackedOnly", "Count tracked (pinned) quests only", y) y = CreateCheckbox(content, "showIncompleteQuestBar", "Show uncompleted quest XP bar", y) + y = CreateCheckbox(content, "showTicks", "Show XP ticks", y) + y = CreateSlider(content, "tickOpacity", "Tick opacity", y, 10, 100, 1) y = y - 10 y = CreateHeader(content, "Bar Size", y) diff --git a/UI.lua b/UI.lua index 4923312..c58c1c7 100644 --- a/UI.lua +++ b/UI.lua @@ -128,6 +128,18 @@ function F.UI.Create() -- Main XP Bar F.BarMain = F.UI.CreateStatusBar(f, "ARTWORK", 1, CFG.colorMain) + -- XP Ticks (20 segments) + local tickContainer = CreateFrame("Frame", nil, f) + tickContainer:SetAllPoints() + tickContainer.ticks = {} + for i = 1, 19 do + local tick = tickContainer:CreateTexture(nil, "OVERLAY") + tick:SetColorTexture(0, 0, 0, 0.35) + tick:SetWidth(1) + tickContainer.ticks[i] = tick + end + F.TickContainer = tickContainer + local overlay = CreateFrame("Frame", nil, f) overlay:SetAllPoints() overlay:SetFrameLevel(f:GetFrameLevel() + 10) @@ -217,7 +229,45 @@ function F.UI.Update() local db = F.DB if db and db.barWidth and db.barHeight then - F.Frame:SetSize(db.barWidth, db.barHeight) + local width = db.barWidth + if width then + local scale = F.Frame:GetEffectiveScale() or 1 + local stepPixels = math.floor(((width / 20) * scale) + 0.5) + width = (stepPixels / scale) * 20 + end + F.Frame:SetSize(width or db.barWidth, db.barHeight) + end + + if F.TickContainer then + if db and db.showTicks then + local width = F.Frame:GetWidth() + local height = F.Frame:GetHeight() + if width and width > 0 then + local step = width / 20 + local scale = F.Frame:GetEffectiveScale() or 1 + local opacity = 0.35 + if db and type(db.tickOpacity) == "number" then + opacity = db.tickOpacity + end + for i = 1, 19 do + local tick = F.TickContainer.ticks[i] + if tick then + local x = step * i + x = math.floor((x * scale) + 0.5) / scale + tick:ClearAllPoints() + tick:SetColorTexture(0, 0, 0, opacity) + tick:SetPoint("TOPLEFT", F.Frame, "TOPLEFT", x, 0) + tick:SetPoint("BOTTOMLEFT", F.Frame, "BOTTOMLEFT", x, 0) + tick:Show() + end + end + F.TickContainer:Show() + else + F.TickContainer:Hide() + end + else + F.TickContainer:Hide() + end end local function resolveColor(color, fallback)