···156156 return y - 52
157157end
158158159159+local function CreateSliderWithInput(parent, key, label, y, minValue, maxValue, step, inputWidth)
160160+ local name = "NXP_Options_" .. key .. "Slider"
161161+ local slider = CreateFrame("Slider", name, parent, "OptionsSliderTemplate")
162162+ slider:SetPoint("TOPLEFT", parent, "TOPLEFT", 16, y)
163163+ slider:SetMinMaxValues(minValue, maxValue)
164164+ slider:SetValueStep(step)
165165+ slider:SetObeyStepOnDrag(true)
166166+167167+ local labelText = _G[name .. "Text"]
168168+ local lowText = _G[name .. "Low"]
169169+ local highText = _G[name .. "High"]
170170+ if labelText then labelText:SetText(label) end
171171+ if lowText then lowText:SetText(tostring(minValue)) end
172172+ if highText then highText:SetText(tostring(maxValue)) end
173173+174174+ local edit = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
175175+ edit:SetAutoFocus(false)
176176+ edit:SetSize(inputWidth or 60, 20)
177177+ edit:SetPoint("LEFT", slider, "RIGHT", 12, 0)
178178+ edit:SetNumeric(true)
179179+180180+ slider:SetScript("OnValueChanged", function(self, value)
181181+ if self._updating then return end
182182+ local rounded = math.floor(value + 0.5)
183183+ if step and step < 1 then
184184+ rounded = value
185185+ end
186186+ self._updating = true
187187+ self:SetValue(rounded)
188188+ self._updating = false
189189+ edit:SetNumber(rounded)
190190+ SetNumericOption(key, rounded)
191191+ end)
192192+193193+ local function commitEdit()
194194+ local value = tonumber(edit:GetText())
195195+ if not value then return end
196196+ if value < minValue then value = minValue end
197197+ if value > maxValue then value = maxValue end
198198+ slider._updating = true
199199+ slider:SetValue(value)
200200+ slider._updating = false
201201+ edit:SetNumber(value)
202202+ SetNumericOption(key, value)
203203+ end
204204+205205+ edit:SetScript("OnEnterPressed", function(self)
206206+ commitEdit()
207207+ self:ClearFocus()
208208+ end)
209209+210210+ edit:SetScript("OnEditFocusLost", function()
211211+ commitEdit()
212212+ end)
213213+214214+ controls[key] = { type = "offset", slider = slider, edit = edit }
215215+ return y - 52
216216+end
217217+159218local function BuildMediaList(kind, defaultLabel, defaultValue)
160219 local list = {}
161220 local order = {}
···306365 local r, g, b, a = GetColorOption(key, control.fallback)
307366 local tex = control.widget:GetNormalTexture()
308367 if tex then tex:SetColorTexture(r, g, b, a) end
368368+ elseif control.type == "offset" then
369369+ local value = F.DB[key]
370370+ if value == nil then value = defaults[key] end
371371+ if value == nil then value = 0 end
372372+ control.slider._updating = true
373373+ control.slider:SetValue(tonumber(value) or 0)
374374+ control.slider._updating = false
375375+ control.edit:SetNumber(tonumber(value) or 0)
309376 elseif control.type == "dropdown" then
310377 local defaults = F.Config or {}
311378 local value = F.DB[key]
···376443 y = CreateCheckbox(content, "showTicks", "Show XP ticks", y)
377444 y = y - 6
378445 y = CreateSlider(content, "tickOpacity", "Tick opacity", y, 10, 100, 1)
446446+447447+ y = y - 10
448448+ y = CreateHeader(content, "Position", y)
449449+ y = y - 6
450450+ local anchorList = {
451451+ TOP = "Top",
452452+ BOTTOM = "Bottom",
453453+ LEFT = "Left",
454454+ RIGHT = "Right",
455455+ CENTER = "Center",
456456+ }
457457+ local anchorOrder = { "TOP", "BOTTOM", "LEFT", "RIGHT", "CENTER" }
458458+ y = CreateDropdown(content, "anchorPoint", "Anchor position", y, anchorList, anchorOrder)
459459+ y = CreateSliderWithInput(content, "offsetX", "X offset", y, -1000, 1000, 1, 60)
460460+ y = CreateSliderWithInput(content, "offsetY", "Y offset", y, -1000, 1000, 1, 60)
379461380462 y = y - 10
381463 y = CreateHeader(content, "Bar Size", y)
+13-72
UI.lua
···3232function F.UI.Create()
3333 local f = CreateFrame("Frame", "NXP_Frame", UIParent)
3434 f:SetSize(CFG.width, CFG.height)
3535- f:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 260) -- Default Position
3535+ f:SetPoint("TOP", UIParent, "TOP", 0, 100) -- Default Position
3636 f:SetFrameStrata("LOW")
37373838- -- Enable dragging (only while Shift is held)
3939- f:SetMovable(true)
3838+ f:SetMovable(false)
4039 f:EnableMouse(false)
4141- f:RegisterForDrag("LeftButton")
4242-4343- local function stopAndMaybeSnap(self)
4444- if self.__nxb_moving then
4545- self:StopMovingOrSizing()
4646- self.__nxb_moving = nil
4747-4848- local fx, fy = self:GetCenter()
4949- if fx and fy then
5050- local cx, cy = UIParent:GetCenter()
5151- if cx and cy then
5252- local dx, dy = fx - cx, fy - cy
5353- local distSq = dx * dx + dy * dy
5454- local snapRadius = 40
5555- if distSq <= (snapRadius * snapRadius) then
5656- self:ClearAllPoints()
5757- self:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
5858- end
5959- end
6060- end
6161-6262- self:SetScript("OnUpdate", nil)
6363- end
6464- end
6565-6666- f:SetScript("OnDragStart", function(self)
6767- if IsShiftKeyDown() then
6868- self:StartMoving()
6969- self.__nxb_moving = true
7070-7171- self:SetScript("OnUpdate", function(self, elapsed)
7272- if not IsShiftKeyDown() or not IsMouseButtonDown("LeftButton") then
7373- stopAndMaybeSnap(self)
7474- end
7575- end)
7676- end
7777- end)
7878-7979- f:SetScript("OnDragStop", stopAndMaybeSnap)
8080-8181- f:SetScript("OnMouseDown", function(self, button)
8282- if button == "LeftButton" and IsShiftKeyDown() then
8383- self:StartMoving()
8484- self.__nxb_moving = true
8585-8686- self:SetScript("OnUpdate", function(self, elapsed)
8787- if not IsShiftKeyDown() or not IsMouseButtonDown("LeftButton") then
8888- stopAndMaybeSnap(self)
8989- end
9090- end)
9191- end
9292- end)
9393-9494- f:SetScript("OnMouseUp", function(self, button)
9595- if button == "LeftButton" then
9696- stopAndMaybeSnap(self)
9797- end
9898- end)
9999-100100- f:RegisterEvent("MODIFIER_STATE_CHANGED")
101101- f:SetScript("OnEvent", function(self, event, key, state)
102102- if event == "MODIFIER_STATE_CHANGED" then
103103- -- Enable/disable clicks based on Shift state
104104- self:EnableMouse(IsShiftKeyDown())
105105- if not IsShiftKeyDown() and self.__nxb_moving then
106106- stopAndMaybeSnap(self)
107107- end
108108- end
109109- end)
1104011141 F.Frame = f
11242···236166 width = (stepPixels / scale) * 20
237167 end
238168 F.Frame:SetSize(width or db.barWidth, db.barHeight)
169169+ end
170170+171171+ if db then
172172+ local anchor = db.anchorPoint or "TOP"
173173+ local x = tonumber(db.offsetX) or 0
174174+ local y = tonumber(db.offsetY) or 0
175175+ if anchor == "TOP" then
176176+ y = -y
177177+ end
178178+ F.Frame:ClearAllPoints()
179179+ F.Frame:SetPoint(anchor, UIParent, anchor, x, y)
239180 end
240181241182 if F.TickContainer then