DopingControl v0.6.1
This commit is contained in:
+273
@@ -0,0 +1,273 @@
|
||||
-- DopingControl ui/widgets.lua
|
||||
-- Shared UI building blocks: panel backdrop, pooled-widget factories
|
||||
-- (cell / pill / badge / button), tooltip helpers, pfUI-aware font helper,
|
||||
-- change-guarded setters (only touch a region when the value changed).
|
||||
--
|
||||
-- Factory + pooling patterns follow common 1.12 addon practice
|
||||
-- (pfUI-style WHITE8X8 backdrops, pooled regions, save-and-call hooks).
|
||||
--
|
||||
-- Pure Lua 5.0 dofile-loadable: top level only defines tables/functions;
|
||||
-- CreateFrame & friends are only referenced INSIDE factory functions, which
|
||||
-- are never called offline.
|
||||
|
||||
DopingControl = DopingControl or {}
|
||||
local DC = DopingControl
|
||||
|
||||
DC_Widgets = DC_Widgets or {}
|
||||
local W = DC_Widgets
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Texture / font constants
|
||||
-- ------------------------------------------------------------------
|
||||
W.SOLID_TEX = "Interface\\Buttons\\WHITE8X8" -- 1px-border backdrop base
|
||||
W.FONT = "Fonts\\FRIZQT__.TTF" -- default client font
|
||||
W.CHECK_TEX = "Interface\\Buttons\\UI-CheckBox-Check" -- HAS glyph (tinted green)
|
||||
W.CROSS_TEX = "Interface\\Buttons\\UI-GroupLoot-Pass-Up" -- MISSING glyph (tinted red)
|
||||
|
||||
-- Main window backdrop (textures shipped in DopingControl\textures\).
|
||||
W.PANEL_BACKDROP = {
|
||||
bgFile = "Interface\\AddOns\\DopingControl\\textures\\panel_bg",
|
||||
edgeFile = "Interface\\AddOns\\DopingControl\\textures\\panel_border",
|
||||
tile = true, tileSize = 128, edgeSize = 16,
|
||||
insets = { left = 5, right = 5, top = 5, bottom = 5 },
|
||||
}
|
||||
|
||||
-- Solid 1px-border backdrop for cells/pills/badges/buttons (pfUI-style
|
||||
-- WHITE8X8 recipe; bg + border colored via SetBackdropColor /
|
||||
-- SetBackdropBorderColor).
|
||||
W.SOLID_BACKDROP = {
|
||||
bgFile = W.SOLID_TEX,
|
||||
edgeFile = W.SOLID_TEX,
|
||||
tile = false, edgeSize = 1,
|
||||
insets = { left = 1, right = 1, top = 1, bottom = 1 },
|
||||
}
|
||||
|
||||
W.WHITE = { r = 1, g = 1, b = 1 }
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Font helper (we keep OUR pixel
|
||||
-- size -- the matrix layout depends on it -- and only take pfUI's font
|
||||
-- FAMILY when pfUI is present; forcing pfUI's global font size would break
|
||||
-- the 30x23 cell grid).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.ApplyFont(fs, size)
|
||||
size = size or 10
|
||||
if pfUI and pfUI.font_default then
|
||||
fs:SetFont(pfUI.font_default, size)
|
||||
else
|
||||
fs:SetFont(W.FONT, size)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Change-guarded setters (convention: cache last-applied value on the
|
||||
-- region as dcLast*; only call the real setter when the value changed.
|
||||
-- Color guards compare by TABLE REFERENCE -- callers always pass the
|
||||
-- shared DC.COLORS / DC.QUALITY tables, so this is exact and zero-alloc).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.SetTextG(fs, text)
|
||||
if fs.dcLastText ~= text then
|
||||
fs.dcLastText = text
|
||||
fs:SetText(text)
|
||||
end
|
||||
end
|
||||
|
||||
function W.SetTextColorG(fs, c)
|
||||
if fs.dcLastColor ~= c then
|
||||
fs.dcLastColor = c
|
||||
fs:SetTextColor(c.r, c.g, c.b)
|
||||
end
|
||||
end
|
||||
|
||||
function W.SetBackdropG(f, bg, border)
|
||||
if f.dcLastBg ~= bg then
|
||||
f.dcLastBg = bg
|
||||
f:SetBackdropColor(bg.r, bg.g, bg.b, bg.a or 1)
|
||||
end
|
||||
if f.dcLastBorder ~= border then
|
||||
f.dcLastBorder = border
|
||||
f:SetBackdropBorderColor(border.r, border.g, border.b, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function W.SetTextureG(tex, path)
|
||||
if tex.dcLastTex ~= path then
|
||||
tex.dcLastTex = path
|
||||
tex:SetTexture(path)
|
||||
end
|
||||
end
|
||||
|
||||
function W.SetVertexG(tex, c)
|
||||
if tex.dcLastVertex ~= c then
|
||||
tex.dcLastVertex = c
|
||||
tex:SetVertexColor(c.r, c.g, c.b)
|
||||
end
|
||||
end
|
||||
|
||||
function W.SetAlphaG(region, a)
|
||||
if region.dcLastAlpha ~= a then
|
||||
region.dcLastAlpha = a
|
||||
region:SetAlpha(a)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- FontString factory
|
||||
-- ------------------------------------------------------------------
|
||||
function W.MakeText(parent, size, color, layer)
|
||||
local fs = parent:CreateFontString(nil, layer or "OVERLAY")
|
||||
W.ApplyFont(fs, size)
|
||||
if color then
|
||||
W.SetTextColorG(fs, color)
|
||||
end
|
||||
return fs
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Cell factory: 30x23 state cell (the 30x23 size is part of the fixed
|
||||
-- visual layout). Carries one texture region (check/cross glyph OR trinket
|
||||
-- item icon) and one FontString (?, skip dot, trinket monogram); the
|
||||
-- matrix paint code shows exactly one of them per state.
|
||||
-- Pool children stay anonymous (documented factory exception).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.MakeCell(parent, name, w, h)
|
||||
local c = CreateFrame("Frame", name, parent)
|
||||
c:SetWidth(w or 30)
|
||||
c:SetHeight(h or 23)
|
||||
c:SetBackdrop(W.SOLID_BACKDROP)
|
||||
c:EnableMouse(true)
|
||||
c.icon = c:CreateTexture(nil, "ARTWORK")
|
||||
c.icon:SetPoint("CENTER", c, "CENTER", 0, 0)
|
||||
c.icon:SetWidth(16)
|
||||
c.icon:SetHeight(16)
|
||||
c.icon:Hide()
|
||||
c.text = c:CreateFontString(nil, "OVERLAY")
|
||||
W.ApplyFont(c.text, 9)
|
||||
c.text:SetPoint("CENTER", c, "CENTER", 0, 0)
|
||||
return c
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Pill factory (ready pill, coverage pill): bordered mini frame with a
|
||||
-- centered FontString; width is adjusted by the caller to fit the text.
|
||||
-- ------------------------------------------------------------------
|
||||
function W.MakePill(parent, name)
|
||||
local p = CreateFrame("Frame", name, parent)
|
||||
p:SetWidth(70)
|
||||
p:SetHeight(16)
|
||||
p:SetBackdrop(W.SOLID_BACKDROP)
|
||||
p:EnableMouse(true)
|
||||
p.text = p:CreateFontString(nil, "OVERLAY")
|
||||
W.ApplyFont(p.text, 9)
|
||||
p.text:SetPoint("CENTER", p, "CENTER", 0, 0)
|
||||
return p
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Role badge factory: clickable bordered button with centered label.
|
||||
-- Suggested roles render with a "?" suffix + dimmer border (matrix paints
|
||||
-- that -- 1.12 has no dashed borders, see the adaptation note there).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.MakeBadge(parent, name)
|
||||
local b = CreateFrame("Button", name, parent)
|
||||
b:SetWidth(56)
|
||||
b:SetHeight(16)
|
||||
b:SetBackdrop(W.SOLID_BACKDROP)
|
||||
b.text = b:CreateFontString(nil, "OVERLAY")
|
||||
W.ApplyFont(b.text, 8)
|
||||
b.text:SetPoint("CENTER", b, "CENTER", 0, 0)
|
||||
b:RegisterForClicks("LeftButtonUp")
|
||||
return b
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Dark gold-trim button (titlebar Scan/Report/Options/X).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.MakeButton(parent, name, label, width, height)
|
||||
local C = DC.COLORS
|
||||
local b = CreateFrame("Button", name, parent)
|
||||
b:SetWidth(width or 64)
|
||||
b:SetHeight(height or 19)
|
||||
b:SetBackdrop(W.SOLID_BACKDROP)
|
||||
W.SetBackdropG(b, C.panel2, C.goldSoft)
|
||||
b.text = b:CreateFontString(nil, "OVERLAY")
|
||||
W.ApplyFont(b.text, 10)
|
||||
b.text:SetPoint("CENTER", b, "CENTER", 0, 0)
|
||||
W.SetTextColorG(b.text, C.goldHi)
|
||||
b.text:SetText(label)
|
||||
b:SetScript("OnEnter", function()
|
||||
W.SetBackdropG(this, C.panel3, C.gold)
|
||||
end)
|
||||
b:SetScript("OnLeave", function()
|
||||
W.SetBackdropG(this, C.panel2, C.goldSoft)
|
||||
end)
|
||||
return b
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Tooltip helpers. Convention: the builder only ADDS
|
||||
-- lines; AttachTooltip calls SetOwner before and Show after -- AddLine
|
||||
-- never calls Show itself.
|
||||
-- AttachTooltip CHAINS any existing OnEnter/OnLeave (no HookScript on
|
||||
-- 1.12 -- standard save-and-call pattern).
|
||||
-- ------------------------------------------------------------------
|
||||
function W.TipLine(text, c, wrap)
|
||||
if not GameTooltip then
|
||||
return
|
||||
end
|
||||
local r, g, b = 1, 1, 1
|
||||
if c then
|
||||
r, g, b = c.r, c.g, c.b
|
||||
end
|
||||
if wrap then
|
||||
GameTooltip:AddLine(text, r, g, b, 1)
|
||||
else
|
||||
GameTooltip:AddLine(text, r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
-- Two-column tooltip line: label left, value flush RIGHT. This is what
|
||||
-- makes a breakdown read like an addition on paper -- the values line up
|
||||
-- in a column instead of trailing their labels at ragged positions. 1.12
|
||||
-- has no monospace font and no tab stops; AddDoubleLine is the only way to
|
||||
-- get a right-aligned column, and it exists in this client's FrameXML.
|
||||
-- `cr` defaults to the label color when omitted.
|
||||
function W.TipDouble(left, right, c, cr)
|
||||
if not GameTooltip then
|
||||
return
|
||||
end
|
||||
local r, g, b = 1, 1, 1
|
||||
if c then
|
||||
r, g, b = c.r, c.g, c.b
|
||||
end
|
||||
local r2, g2, b2 = r, g, b
|
||||
if cr then
|
||||
r2, g2, b2 = cr.r, cr.g, cr.b
|
||||
end
|
||||
GameTooltip:AddDoubleLine(left, right, r, g, b, r2, g2, b2)
|
||||
end
|
||||
|
||||
function W.AttachTooltip(frame, builder, anchor)
|
||||
frame.dcTipBuilder = builder
|
||||
frame.dcTipAnchor = anchor or "ANCHOR_LEFT"
|
||||
frame.dcOldEnter = frame:GetScript("OnEnter")
|
||||
frame.dcOldLeave = frame:GetScript("OnLeave")
|
||||
frame:SetScript("OnEnter", function()
|
||||
if this.dcOldEnter then
|
||||
this.dcOldEnter()
|
||||
end
|
||||
if GameTooltip and this.dcTipBuilder then
|
||||
GameTooltip:SetOwner(this, this.dcTipAnchor)
|
||||
this.dcTipBuilder(this)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end)
|
||||
frame:SetScript("OnLeave", function()
|
||||
if this.dcOldLeave then
|
||||
this.dcOldLeave()
|
||||
end
|
||||
if GameTooltip then
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user