419 lines
12 KiB
Lua
419 lines
12 KiB
Lua
PTGuiComponent = {}
|
|
PTUtil.SetEnvironment(PTGuiComponent)
|
|
local _G = getfenv(0)
|
|
PTGuiComponent.__index = PTGuiComponent
|
|
|
|
-- A static flag to verify if this is a gui component
|
|
PTGuiComponent.IsPuppeteerGui = true
|
|
|
|
PTGuiComponent.TypeName = "BASE_COMPONENT"
|
|
|
|
-- The primary frame associated with the set of components
|
|
PTGuiComponent.Primary = nil
|
|
-- The raw frame associated with the component
|
|
PTGuiComponent.Frame = nil
|
|
-- All gui component instances associated with the component, including itself(named "Frame")
|
|
PTGuiComponent.Components = {}
|
|
|
|
-- Permanent frames cannot be recycled
|
|
PTGuiComponent.Permanent = false
|
|
|
|
PTGuiComponent.FrameCount = 0
|
|
|
|
function PTGuiComponent:Extend(typeName)
|
|
local obj = {}
|
|
setmetatable(obj, self)
|
|
obj.TypeName = typeName
|
|
obj.super = self
|
|
obj.__index = obj
|
|
return obj
|
|
end
|
|
|
|
-- Called when a component is acquired
|
|
function PTGuiComponent:OnAcquire()
|
|
self:Show()
|
|
end
|
|
|
|
-- Responsible for cleaning up a component, putting it in a default state
|
|
function PTGuiComponent:OnDispose()
|
|
self:Hide()
|
|
self:ClearAllPoints()
|
|
self:SetSize(0, 0)
|
|
self:SetParent(nil)
|
|
if self.HasScript and self:HasScript("OnClick") then
|
|
self:OnClick(nil)
|
|
end
|
|
|
|
if self.DisposeHandler then
|
|
self:DisposeHandler()
|
|
self.DisposeHandler = nil
|
|
end
|
|
end
|
|
|
|
function PTGuiComponent:Dispose()
|
|
if not self:IsPermanent() then -- Permanent components aren't recycled, but can try to hide themselves
|
|
PTGuiLib.Recycle(self)
|
|
end
|
|
|
|
self:OnDispose()
|
|
end
|
|
|
|
-- Set a special handler that is called when this component is being disposed.
|
|
-- Should be used for cleaning up things components don't normally clean up.
|
|
function PTGuiComponent:SetDisposeHandler(handler)
|
|
self.DisposeHandler = handler
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:SetPermanent()
|
|
self.Permanent = true
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:IsPermanent()
|
|
return self.Permanent
|
|
end
|
|
|
|
function PTGuiComponent:Type()
|
|
return self.TypeName
|
|
end
|
|
|
|
function PTGuiComponent:GenerateName()
|
|
self.FrameCount = self.FrameCount + 1
|
|
return "PTGui_"..self:Type()..self.FrameCount
|
|
end
|
|
|
|
function PTGuiComponent:SetHandle(frame)
|
|
self.Frame = frame
|
|
self:AddComponent("Frame", self)
|
|
frame.GuiInstance = self
|
|
self:SetPrimary()
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:GetHandle()
|
|
return self.Frame
|
|
end
|
|
|
|
function PTGuiComponent:IsInstance()
|
|
return self.Frame ~= nil
|
|
end
|
|
|
|
function PTGuiComponent:IsPrimary()
|
|
return self.Primary == self.Frame
|
|
end
|
|
|
|
function PTGuiComponent:GetPrimary()
|
|
return self.Primary
|
|
end
|
|
|
|
-- Sets this component as the primary for all associated components
|
|
function PTGuiComponent:SetPrimary()
|
|
for _, component in pairs(self.Components) do
|
|
component.Primary = self
|
|
end
|
|
end
|
|
|
|
function PTGuiComponent:Import(returnSelf, ...)
|
|
self:ImportComponent(nil, returnSelf, arg)
|
|
end
|
|
|
|
function PTGuiComponent:ImportComponent(frameName, returnSelf, ...)
|
|
frameName = frameName or "Frame"
|
|
for _, import in ipairs(arg) do
|
|
if type(import) == "table" then
|
|
for _, import in ipairs(import) do
|
|
self:DoImport(frameName, returnSelf, import)
|
|
end
|
|
else
|
|
self:DoImport(frameName, returnSelf, import)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Instance imports are faster and static imports consume less memory.
|
|
-- Instance importing must be done after the component is added.
|
|
function PTGuiComponent:DoImport(frameName, returnSelf, import)
|
|
if self:IsInstance() then -- Prefer an instance import
|
|
local frame = self:GetComponent(frameName):GetHandle()
|
|
local func = frame[import]
|
|
if returnSelf then
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
func(frame, a1, a2, a3, a4, a5)
|
|
return self
|
|
end
|
|
else
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
return func(frame, a1, a2, a3, a4, a5)
|
|
end
|
|
end
|
|
elseif frameName == "Frame" then -- Optimized static import for the handle
|
|
if returnSelf then
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
local frame = self.Frame
|
|
frame[import](frame, a1, a2, a3, a4, a5)
|
|
return self
|
|
end
|
|
else
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
local frame = self.Frame
|
|
return frame[import](frame, a1, a2, a3, a4, a5)
|
|
end
|
|
end
|
|
else -- Static import for other components
|
|
if returnSelf then
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
local frame = self.Components[frameName]:GetHandle()
|
|
frame[import](frame, a1, a2, a3, a4, a5)
|
|
return self
|
|
end
|
|
else
|
|
self[import] = function(self, a1, a2, a3, a4, a5)
|
|
local frame = self.Components[frameName]:GetHandle()
|
|
return frame[import](frame, a1, a2, a3, a4, a5)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function PTGuiComponent:CreateGetter(componentName, funcName)
|
|
self[funcName or ("Get"..componentName)] = function(self)
|
|
return self:GetComponent(componentName)
|
|
end
|
|
end
|
|
|
|
function PTGuiComponent:GetContainer()
|
|
return self.Frame
|
|
end
|
|
|
|
function PTGuiComponent:GetAnchor()
|
|
return self.Frame
|
|
end
|
|
|
|
function PTGuiComponent:AddComponent(name, component)
|
|
if self.Components == PTGuiComponent.Components then
|
|
self.Components = {}
|
|
end
|
|
self.Components[name] = component
|
|
end
|
|
|
|
function PTGuiComponent:GetComponent(name)
|
|
return self.Components[name]
|
|
end
|
|
|
|
function PTGuiComponent:GetComponents()
|
|
return self.Components
|
|
end
|
|
|
|
function PTGuiComponent:SetParent(obj)
|
|
if obj and obj.IsPuppeteerGui then
|
|
obj = obj:GetContainer()
|
|
end
|
|
self:GetHandle():SetParent(obj)
|
|
PTUtil.FixFrameLevels(self:GetHandle())
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:SetSize(width, height)
|
|
self:SetWidth(width)
|
|
self:SetHeight(height)
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:SetScript(scriptName, script, noSelf)
|
|
self:GetHandle():SetScript(scriptName, script and (noSelf and script or function() script(self) end) or nil)
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:HookScript(scriptName, script)
|
|
local prevScript = self:GetScript(scriptName)
|
|
self:GetHandle():SetScript(scriptName, function()
|
|
if prevScript then
|
|
prevScript(self)
|
|
end
|
|
script(self)
|
|
end)
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:OnClick(script, noSelf)
|
|
return self:SetScript("OnClick", script, noSelf)
|
|
end
|
|
|
|
function PTGuiComponent:SetPoint(point, relativeFrame, relativePoint, xOffset, yOffset)
|
|
if type(relativeFrame) == "table" and relativeFrame.IsPuppeteerGui then
|
|
relativeFrame = relativeFrame:GetAnchor()
|
|
end
|
|
self:GetHandle():SetPoint(point, relativeFrame, relativePoint, xOffset, yOffset)
|
|
return self
|
|
end
|
|
|
|
PTGuiComponent.BACKGROUND_TOOLTIP = 1
|
|
PTGuiComponent.BACKGROUND_DIALOG = 2
|
|
function PTGuiComponent:SetSimpleBackground(type, diff)
|
|
type = type or PTGuiComponent.BACKGROUND_TOOLTIP
|
|
local background
|
|
if type == PTGuiComponent.BACKGROUND_TOOLTIP then
|
|
background = {
|
|
frameBackdrop = {
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeSize = 11,
|
|
tile = true
|
|
},
|
|
frameBackdropColor = {0.09, 0.09, 0.19},
|
|
frameBorderColor = nil,
|
|
borderBackdrop = {
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
edgeSize = 11,
|
|
tileSize = 11,
|
|
tile = true
|
|
},
|
|
borderBackdropColor = nil,
|
|
borderBorderColor = {0.8, 0.8, 0.8},
|
|
borderPadding = 2
|
|
}
|
|
elseif type == PTGuiComponent.BACKGROUND_DIALOG then
|
|
background = {
|
|
frameBackdrop = {
|
|
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
|
edgeSize = 32,
|
|
tile = true,
|
|
tileSize = 32
|
|
},
|
|
borderBackdrop = {
|
|
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
|
edgeSize = 32,
|
|
tile = true,
|
|
tileSize = 32
|
|
},
|
|
borderPadding = 11
|
|
}
|
|
end
|
|
if diff then
|
|
for k, v in pairs(diff) do
|
|
background[k] = v
|
|
end
|
|
end
|
|
return self:SetBackground(background)
|
|
end
|
|
|
|
function PTGuiComponent:SetBackground(params)
|
|
local frame = self:GetHandle()
|
|
|
|
frame:SetBackdrop(nil)
|
|
frame:SetBackdropColor()
|
|
frame:SetBackdropBorderColor()
|
|
if frame.guiBorder then
|
|
frame.guiBorder:Hide()
|
|
frame.guiBorder:SetBackdrop(nil)
|
|
frame.guiBorder:SetBackdropColor()
|
|
frame.guiBorder:SetBackdropBorderColor()
|
|
end
|
|
|
|
if not params then
|
|
return self
|
|
end
|
|
|
|
if params.frameBackdrop then
|
|
frame:SetBackdrop(params.frameBackdrop)
|
|
if params.frameBackdropColor then
|
|
frame:SetBackdropColor(unpack(params.frameBackdropColor))
|
|
end
|
|
if params.frameBorderColor then
|
|
frame:SetBackdropColor(unpack(params.frameBorderColor))
|
|
end
|
|
end
|
|
|
|
if params.borderBackdrop then
|
|
local border = frame.guiBorder or CreateFrame("Frame", nil, frame)
|
|
frame.guiBorder = border
|
|
frame.guiBorder:Show()
|
|
local padding = params.borderPadding or 0
|
|
border:SetPoint("TOPLEFT", frame, "TOPLEFT", -padding, padding)
|
|
border:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", padding, -padding)
|
|
border:SetBackdrop(params.borderBackdrop)
|
|
border:SetFrameLevel(frame:GetFrameLevel())
|
|
if params.borderBackdropColor then
|
|
border:SetBackdropColor(unpack(params.borderBackdropColor))
|
|
end
|
|
if params.borderBorderColor then
|
|
border:SetBackdropBorderColor(unpack(params.borderBorderColor))
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
-- TODO: Handle cleanup of tooltips for disposed components
|
|
local infoTooltip = CreateFrame("GameTooltip", "PTGuiInfoTooltip", UIParent, "GameTooltipTemplate")
|
|
|
|
local singleTextArray = {}
|
|
local function ShowTooltip(attachTo, texts)
|
|
infoTooltip:SetOwner(attachTo, "ANCHOR_RIGHT")
|
|
infoTooltip:SetPoint("RIGHT", attachTo, "LEFT", 0, 0)
|
|
|
|
if type(texts) == "string" then
|
|
singleTextArray[1] = texts
|
|
texts = singleTextArray
|
|
end
|
|
|
|
for i, text in ipairs(texts) do
|
|
if i ~= 1 then
|
|
text = PTUtil.Colorize(text, 1.0, 0.88, 0.3)
|
|
end
|
|
infoTooltip:AddLine(text)
|
|
_G["PTGuiInfoTooltipTextLeft"..i]:SetFont("Fonts\\FRIZQT__.TTF", i == 1 and 14 or 12, "OUTLINE")
|
|
end
|
|
|
|
infoTooltip:Show()
|
|
end
|
|
|
|
function PTGuiComponent:ApplyTooltip(...)
|
|
self:ApplyTooltipToAll(arg)
|
|
return self
|
|
end
|
|
|
|
function PTGuiComponent:ApplyTooltipTo(component, texts)
|
|
local primary = component:GetPrimary():GetHandle()
|
|
local frame = component:GetHandle()
|
|
frame:EnableMouse(true)
|
|
frame:SetScript("OnEnter", function()
|
|
ShowTooltip(primary, texts)
|
|
end)
|
|
frame:SetScript("OnLeave", function()
|
|
infoTooltip:Hide()
|
|
end)
|
|
end
|
|
|
|
local function flattenTexts(element, t)
|
|
if type(element) == "table" then
|
|
for _, e in ipairs(element) do
|
|
flattenTexts(e, t)
|
|
end
|
|
elseif type(element) == "string" then
|
|
table.insert(t, element)
|
|
end
|
|
return t
|
|
end
|
|
|
|
function PTGuiComponent:ApplyTooltipToAll(texts)
|
|
local primary = self:GetPrimary():GetHandle()
|
|
local texts = flattenTexts(texts, {})
|
|
local onEnter = function()
|
|
ShowTooltip(primary, texts)
|
|
end
|
|
local onLeave = function()
|
|
infoTooltip:Hide()
|
|
end
|
|
for _, component in pairs(self:GetComponents()) do
|
|
local frame = component:GetHandle()
|
|
if frame.EnableMouse and frame.HasScript and frame:HasScript("OnEnter") then
|
|
frame:EnableMouse(true)
|
|
frame:SetScript("OnEnter", onEnter)
|
|
frame:SetScript("OnLeave", onLeave)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
PTGuiComponent:Import(true, "ClearAllPoints", "SetAllPoints", "SetWidth", "SetHeight", "Show", "Hide", "SetFrameLevel")
|
|
PTGuiComponent:Import(false, "GetWidth", "GetHeight", "GetName", "HasScript", "GetScript", "GetParent", "GetFrameLevel", "IsVisible", "IsShown") |