diff --git a/ThreatPlates_GUI.lua b/ThreatPlates_GUI.lua deleted file mode 100644 index 5f53b99..0000000 --- a/ThreatPlates_GUI.lua +++ /dev/null @@ -1,499 +0,0 @@ ----------------------------------------------------------------------- --- ThreatPlates_GUI.lua --- Configuration GUI panel with scrolling support --- Styled after Kui Nameplates config: dark, minimal, clean --- Standalone - no Ace3 or external config library required --- Compatible with WoW 1.12 (Vanilla / Turtle WoW / Octo WoW) ----------------------------------------------------------------------- - -local addon = ThreatPlates - -addon.GUI = {} - --- GUI frame reference -local guiFrame = nil - --- Kui-style colour constants for GUI -local C = { - BG = { 0.10, 0.10, 0.10, 0.95 }, - BORDER = { 0.30, 0.30, 0.30, 1.00 }, - HEADER_BG = { 0.15, 0.15, 0.15, 1.00 }, - HEADER_TEXT = { 0.75, 0.60, 1.00, 1.00 }, -- Kui purple - ACCENT = { 0.30, 0.70, 1.00, 1.00 }, -- Kui blue - TEXT = { 0.85, 0.85, 0.85, 1.00 }, - TEXT_DIM = { 0.55, 0.55, 0.55, 1.00 }, - BUTTON_BG = { 0.20, 0.20, 0.20, 1.00 }, - BUTTON_HOVER = { 0.25, 0.25, 0.30, 1.00 }, - BUTTON_TEXT = { 0.90, 0.90, 0.90, 1.00 }, - CHECK_ON = { 0.30, 0.70, 1.00, 0.90 }, - CHECK_OFF = { 0.30, 0.30, 0.30, 0.80 }, - SLIDER_BG = { 0.15, 0.15, 0.15, 1.00 }, - SLIDER_FILL = { 0.30, 0.70, 1.00, 0.80 }, - DIVIDER = { 0.25, 0.25, 0.25, 0.60 }, - SOLID = "Interface\\Buttons\\WHITE8x8", -} - --- Layout -local GUI_WIDTH = 320 -local GUI_HEIGHT = 480 -local HEADER_H = 30 -local MARGIN = 14 -local FONT_NORMAL = "Fonts\\FRIZQT__.TTF" -local FONT_SIZE = 10 - --- Widget references for refresh -local widgets = {} - --- ================================================================== --- Helper: safely set backdrop on a frame --- ================================================================== -local function SafeSetBackdrop(frame, backdropTbl) - if frame.SetBackdrop then - frame:SetBackdrop(backdropTbl) - return true - end - return false -end - --- ================================================================== --- Initialize GUI module --- ================================================================== -function addon.GUI:Initialize() - -- Defer creation until first toggle -end - --- ================================================================== --- Create the main GUI frame (Kui-style dark panel with scroll) --- ================================================================== -function addon.GUI:CreateFrame() - if guiFrame then return end - - -- ============================================================== - -- Main window frame - -- ============================================================== - local f = CreateFrame("Frame", "ThreatPlatesGUI", UIParent) - f:SetWidth(GUI_WIDTH) - f:SetHeight(GUI_HEIGHT) - f:SetPoint("CENTER", UIParent, "CENTER", 0, 0) - - SafeSetBackdrop(f, { - bgFile = C.SOLID, - edgeFile = C.SOLID, - tile = false, tileSize = 0, - edgeSize = 1, - }) - f:SetBackdropColor(unpack(C.BG)) - f:SetBackdropBorderColor(unpack(C.BORDER)) - f:SetFrameStrata("DIALOG") - f:SetMovable(true) - f:EnableMouse(true) - f:RegisterForDrag("LeftButton") - f:SetScript("OnDragStart", function() this:StartMoving() end) - f:SetScript("OnDragStop", function() - this:StopMovingOrSizing() - local _, _, point, _, _, x, y = this:GetPoint() - ThreatPlatesDB.guiPos = { point = point, relPoint = point, x = x, y = y } - end) - f:Hide() - - -- ============================================================== - -- Header bar (Kui purple accent) - -- ============================================================== - local header = CreateFrame("Frame", nil, f) - header:SetHeight(HEADER_H) - header:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0) - header:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0) - SafeSetBackdrop(header, { - bgFile = C.SOLID, - edgeFile = C.SOLID, - tile = false, tileSize = 0, - edgeSize = 1, - }) - header:SetBackdropColor(unpack(C.HEADER_BG)) - header:SetBackdropBorderColor(unpack(C.BORDER)) - header:EnableMouse(true) - header:RegisterForDrag("LeftButton") - header:SetScript("OnDragStart", function() f:StartMoving() end) - header:SetScript("OnDragStop", function() - f:StopMovingOrSizing() - local _, _, point, _, _, x, y = f:GetPoint() - ThreatPlatesDB.guiPos = { point = point, relPoint = point, x = x, y = y } - end) - - local headerText = header:CreateFontString(nil, "OVERLAY") - headerText:SetFont(FONT_NORMAL, 12, "OUTLINE") - headerText:SetPoint("CENTER", header, "CENTER", 0, 0) - headerText:SetTextColor(unpack(C.HEADER_TEXT)) - headerText:SetText("ThreatPlates") - - -- Close button - local closeBtn = CreateFrame("Button", nil, header) - closeBtn:SetWidth(24) - closeBtn:SetHeight(20) - closeBtn:SetPoint("RIGHT", header, "RIGHT", -4, 0) - closeBtn:SetNormalTexture(C.SOLID) - closeBtn:GetNormalTexture():SetVertexColor(0.4, 0.4, 0.4, 0.8) - closeBtn:SetHighlightTexture(C.SOLID) - closeBtn:GetHighlightTexture():SetVertexColor(0.6, 0.6, 0.6, 0.8) - closeBtn:SetPushedTexture(C.SOLID) - closeBtn:GetPushedTexture():SetVertexColor(0.3, 0.3, 0.3, 0.8) - - local closeText = closeBtn:CreateFontString(nil, "OVERLAY") - closeText:SetFont(FONT_NORMAL, 10, "OUTLINE") - closeText:SetPoint("CENTER", closeBtn, "CENTER", 0, 0) - closeText:SetTextColor(1, 1, 1, 1) - closeText:SetText("X") - closeBtn:SetFontString(closeText) - - closeBtn:SetScript("OnClick", function() - addon.GUI:Hide() - end) - - -- ============================================================== - -- Scroll frame - allows content to scroll when it overflows - -- ============================================================== - -- The scroll frame sits below the header and fills the rest of the window - local scrollFrame = CreateFrame("ScrollFrame", "ThreatPlatesScrollFrame", f) - scrollFrame:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -HEADER_H) - scrollFrame:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -HEADER_H) - scrollFrame:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0) - scrollFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0) - - -- Scroll bar (vertical) - local scrollBar = CreateFrame("Slider", "ThreatPlatesScrollBar", scrollFrame, "UIPanelScrollBarTemplate") - scrollBar:SetPoint("TOPRIGHT", f, "TOPRIGHT", -4, -HEADER_H - 8) - scrollBar:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -4, 8) - scrollBar:SetWidth(16) - scrollBar:SetMinMaxValues(0, 1000) - scrollBar:SetValueStep(20) - scrollBar:SetValue(0) - - -- Style the scrollbar thumb and background to Kui look - local scrollName = scrollBar:GetName() - local scrollThumb = getglobal(scrollName .. "ThumbTexture") - if scrollThumb then - scrollThumb:SetTexture(C.SOLID) - scrollThumb:SetVertexColor(unpack(C.ACCENT)) - end - - -- Scroll child - the actual content frame that holds all settings - local scrollChild = CreateFrame("Frame", "ThreatPlatesScrollChild", scrollFrame) - scrollChild:SetWidth(GUI_WIDTH - 30) -- leave room for scrollbar - -- Height will be set after building content based on total y offset - scrollFrame:SetScrollChild(scrollChild) - - -- Connect scrollbar to scrollframe - scrollBar:SetScript("OnValueChanged", function() - scrollFrame:SetVerticalScroll(this:GetValue()) - end) - - -- Mouse wheel scrolling on the main frame - f:EnableMouseWheel(true) - f:SetScript("OnMouseWheel", function() - local delta = arg1 - local current = scrollBar:GetValue() - local step = 40 - if delta > 0 then - scrollBar:SetValue(math.max(0, current - step)) - else - scrollBar:SetValue(math.min(1000, current + step)) - end - end) - - f.scrollFrame = scrollFrame - f.scrollBar = scrollBar - f.scrollChild = scrollChild - - -- Build settings into the scroll child - widgets = {} - local totalHeight = self:BuildSettings(scrollChild) - - -- Set the scroll child height to the actual content height - scrollChild:SetHeight(totalHeight + MARGIN) - - -- Update scrollbar max based on content vs visible area - local visibleH = GUI_HEIGHT - HEADER_H - if totalHeight + MARGIN > visibleH then - scrollBar:SetMinMaxValues(0, totalHeight + MARGIN - visibleH) - else - scrollBar:SetMinMaxValues(0, 0) - scrollBar:Hide() - end - - -- Restore saved position - if ThreatPlatesDB and ThreatPlatesDB.guiPos then - local pos = ThreatPlatesDB.guiPos - if pos.point and pos.x and pos.y then - f:ClearAllPoints() - f:SetPoint(pos.point, UIParent, pos.relPoint or pos.point, pos.x, pos.y) - end - end - - guiFrame = f -end - --- ================================================================== --- Build all settings controls --- Returns the total content height for scroll setup --- ================================================================== -function addon.GUI:BuildSettings(parent) - local y = 0 - local W = GUI_WIDTH - 30 -- account for scrollbar width - - -- ============================================================== - -- Helper: Section label (Kui-style blue heading) - -- ============================================================== - local function SectionLabel(text) - local label = parent:CreateFontString(nil, "OVERLAY") - label:SetFont(FONT_NORMAL, FONT_SIZE + 1, "OUTLINE") - label:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN, -y) - label:SetTextColor(unpack(C.ACCENT)) - label:SetText(text) - y = y + 20 - - -- Divider line - local divider = parent:CreateTexture(nil, "ARTWORK") - divider:SetTexture(C.SOLID) - divider:SetVertexColor(unpack(C.DIVIDER)) - divider:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN, -y + 8) - divider:SetPoint("TOPRIGHT", parent, "TOPRIGHT", -MARGIN, -y + 8) - divider:SetHeight(1) - y = y + 4 - end - - -- ============================================================== - -- Helper: Checkbox (custom frame-based) - -- ============================================================== - local function CheckBox(labelText, configKey, description) - local btn = CreateFrame("Frame", nil, parent) - btn:SetWidth(18) - btn:SetHeight(18) - btn:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN, -y) - btn:EnableMouse(true) - - SafeSetBackdrop(btn, { - bgFile = C.SOLID, - edgeFile = C.SOLID, - tile = false, tileSize = 0, - edgeSize = 1, - }) - btn:SetBackdropColor(unpack(C.CHECK_OFF)) - btn:SetBackdropBorderColor(unpack(C.BORDER)) - - local check = btn:CreateTexture(nil, "ARTWORK") - check:SetTexture(C.SOLID) - check:SetPoint("TOPLEFT", btn, "TOPLEFT", 3, -3) - check:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -3, 3) - check:SetVertexColor(unpack(C.CHECK_ON)) - check:Hide() - btn.checkMark = check - - btn.checked = false - if ThreatPlatesDB[configKey] then - btn.checked = true - check:Show() - end - - btn:SetScript("OnMouseDown", function() - this.checked = not this.checked - ThreatPlatesDB[configKey] = this.checked - if this.checked then - this.checkMark:Show() - else - this.checkMark:Hide() - end - addon.Nameplates:RecreateAll() - end) - - local label = parent:CreateFontString(nil, "OVERLAY") - label:SetFont(FONT_NORMAL, FONT_SIZE) - label:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN + 24, -y + 1) - label:SetTextColor(unpack(C.TEXT)) - label:SetText(labelText) - - y = y + 18 - - if description then - local desc = parent:CreateFontString(nil, "OVERLAY") - desc:SetFont(FONT_NORMAL, FONT_SIZE - 2) - desc:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN + 24, -y + 3) - desc:SetTextColor(unpack(C.TEXT_DIM)) - desc:SetText(description) - y = y + 14 - end - - y = y + 4 - widgets[configKey] = btn - end - - -- ============================================================== - -- Helper: Slider (Kui-style flat slider) - -- ============================================================== - local function Slider(labelText, configKey, minVal, maxVal, step, suffix) - suffix = suffix or "" - - local label = parent:CreateFontString(nil, "OVERLAY") - label:SetFont(FONT_NORMAL, FONT_SIZE) - label:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN, -y) - label:SetTextColor(unpack(C.TEXT)) - label:SetText(labelText) - y = y + 16 - - local slider = CreateFrame("Slider", "ThreatPlatesSlider_" .. configKey, parent, "OptionsSliderTemplate") - slider:SetWidth(W - 60) - slider:SetHeight(16) - slider:SetPoint("TOPLEFT", parent, "TOPLEFT", MARGIN, -y) - slider:SetOrientation("HORIZONTAL") - slider:SetMinMaxValues(minVal, maxVal) - slider:SetValueStep(step) - slider:SetValue(ThreatPlatesDB[configKey] or minVal) - - local sliderName = slider:GetName() - local bgTexture = getglobal(sliderName .. "BG") - local fillTexture = getglobal(sliderName .. "Fill") - local thumbTexture = getglobal(sliderName .. "Thumb") - - if bgTexture then - bgTexture:SetTexture(C.SOLID) - bgTexture:SetVertexColor(unpack(C.SLIDER_BG)) - end - if fillTexture then - fillTexture:SetTexture(C.SOLID) - fillTexture:SetVertexColor(unpack(C.SLIDER_FILL)) - end - if thumbTexture then - thumbTexture:SetTexture(C.SOLID) - thumbTexture:SetVertexColor(unpack(C.ACCENT)) - end - - local lowText = getglobal(sliderName .. "Low") - local highText = getglobal(sliderName .. "High") - if lowText then lowText:SetText("") end - if highText then highText:SetText("") end - - local valText = parent:CreateFontString(nil, "OVERLAY") - valText:SetFont(FONT_NORMAL, FONT_SIZE - 1) - valText:SetPoint("LEFT", slider, "RIGHT", 6, 0) - valText:SetTextColor(unpack(C.ACCENT)) - local curVal = ThreatPlatesDB[configKey] or minVal - if step < 1 then - valText:SetText(string.format("%.1f", curVal) .. suffix) - else - valText:SetText(math.floor(curVal + 0.5) .. suffix) - end - - slider:SetScript("OnValueChanged", function() - local val = this:GetValue() - val = math.floor(val / step + 0.5) * step - ThreatPlatesDB[configKey] = val - if step < 1 then - valText:SetText(string.format("%.1f", val) .. suffix) - else - valText:SetText(math.floor(val + 0.5) .. suffix) - end - addon.Nameplates:RecreateAll() - end) - - y = y + 24 - widgets[configKey] = slider - end - - -- ============================================================== - -- GENERAL SECTION - -- ============================================================== - SectionLabel("General") - CheckBox("Enable Threat Plates", "enabled", "Show threat bars above nameplates") - CheckBox("Show Threat Text", "showText", "Display percentage in the bar") - CheckBox("Smooth Colours", "smoothColors", "Gradient colour transition") - - -- ============================================================== - -- APPEARANCE SECTION - -- ============================================================== - SectionLabel("Appearance") - Slider("Bar Height", "barHeight", 2, 20, 1, "px") - Slider("Bar Width Scale", "barWidthScale", 0.3, 1.0, 0.05, "") - Slider("Bar Offset Y", "barOffsetY", 0, 20, 1, "px") - Slider("Bar Offset X", "barOffsetX", -50, 50, 0.1, "px") - Slider("Bar Alpha", "barAlpha", 0.1, 1.0, 0.1, "") - Slider("Font Size", "fontSize", 6, 16, 1, "pt") - CheckBox("Font Outline", "fontOutline", "Outlined text for readability") - - -- ============================================================== - -- KUI STYLE SECTION - -- ============================================================== - SectionLabel("Kui Style Effects") - CheckBox("Show Spark", "showSpark", "Bright edge on the bar's leading edge") - CheckBox("Show Fill Background", "showFillBG", "Dim ghost of bar colour behind the bar") - Slider("Fill Alpha", "fillAlpha", 0.05, 0.50, 0.05, "") - CheckBox("Enable Glow", "glowEnabled", "Border glow based on threat level") - CheckBox("Glow as Shadow", "glowAsShadow", "Subtle shadow instead of bright glow") - Slider("Glow Size", "glowSize", 1, 8, 1, "px") - - -- ============================================================== - -- FILTER SECTION - -- ============================================================== - SectionLabel("Display Filters") - CheckBox("Show on Hostile", "showOnHostile", "Show threat bars on hostile units") - CheckBox("Show on Neutral", "showOnNeutral", "Show threat bars on neutral units") - CheckBox("Show on Friendly", "showOnFriendly", "Show threat bars on friendly units") - - -- Return total content height for scroll setup - return y -end - --- ================================================================== --- Toggle GUI visibility --- ================================================================== -function addon.GUI:Toggle() - if not guiFrame then - self:CreateFrame() - end - - if guiFrame:IsVisible() then - self:Hide() - else - self:Show() - end -end - --- ================================================================== --- Show the GUI --- ================================================================== -function addon.GUI:Show() - if not guiFrame then - self:CreateFrame() - end - guiFrame:Show() -end - --- ================================================================== --- Hide the GUI --- ================================================================== -function addon.GUI:Hide() - if guiFrame then - guiFrame:Hide() - end -end - --- ================================================================== --- Refresh all GUI values from saved vars --- ================================================================== -function addon.GUI:Refresh() - if not guiFrame then return end - - for key, widget in pairs(widgets) do - -- Our custom checkbox (Frame with .checked field) - if widget.checked ~= nil then - local val = ThreatPlatesDB[key] - widget.checked = val - if val then - widget.checkMark:Show() - else - widget.checkMark:Hide() - end - -- Slider - elseif widget.SetValue then - widget:SetValue(ThreatPlatesDB[key]) - end - end -end