---@type Tinkr, Bastion ---@type Diesal.GUI local DiesalGUI = LibStub("DiesalGUI-2.0") ---@type Diesal.Tools local DiesalTools = LibStub("DiesalTools-2.0") ---@type Diesal.Style local DiesalStyle = LibStub("DiesalStyle-2.0") local Type = "DiesalObjectBase" local Version = 1 ---@class Diesal.GUI.ObjectBase.Methods local ObjectBase = { --#region Diesal.GUI.Objectbase.BaseMethods --#region BlizzardFrameMethods ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase Hide = function(self) self.frame:Hide() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase Show = function(self) self.frame:Show() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param parent Frame SetParent = function(self, parent) local frame = self.frame frame:SetParent(nil) frame:SetParent(parent) self.settings.parent = parent end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase GetWidth = function(self) return self.frame:GetWidth() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase SetWidth = function(self, width) self.settings.width = width self.frame:SetWidth(width) self:FireEvent("OnWidthSet", width) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase GetHeight = function(self) return self.frame:GetHeight() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param height number SetHeight = function(self, height) self.settings.height = height self.frame:SetHeight(height) self:FireEvent("OnHeightSet", height) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@return number width, number height GetSize = function(self) return self.frame:GetSize() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param width number ---@param height number SetSize = function(self, width, height) self.settings.width = width self.settings.height = height --TODO: Transition to SetSize? self.frame:SetSize(width, height) --self.frame:SetHeight(height) --self.frame:SetWidth(width) self:FireEvent("OnWidthSet", width) self:FireEvent("OnHeightSet", height) self:FireEvent("OnSizeSet", width, height) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase IsVisible = function(self) return self.frame:IsVisible() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase IsShown = function(self) return self.frame:IsShown() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase SetPoint = function(self, ...) self.frame:SetPoint(...) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase SetAllPoints = function(self, ...) return self.frame:SetAllPoints(...) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ClearAllPoints = function(self) return self.frame:ClearAllPoints() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase GetNumPoints = function(self) return self.frame:GetNumPoints() end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase GetPoint = function(self, ...) return self.frame:GetPoint(...) end, --#endregion BlizzardFrameMethods ---@class Diesal.GUI.Region.FontString : FontString ---@field defaultFontObject Font ---@class Diesal.GUI.Region.EditBox : EditBox, FontableFrameMixin ---@field defaultFontObject Font ---@class Diesal.GUI.Region.ScrollingMessageFrame : ScrollingMessageFrame ---@field defaultFontObject Font ---@alias Diesal.GUI.Region.Custom ---|Diesal.GUI.Region.FontString ---|Diesal.GUI.Region.EditBox ---|Diesal.GUI.Region.ScrollingMessageFrame ---@alias Diesal.GUI.Parent.Region ---|Frame ---|Texture ---|Diesal.Object --#region DiesalObjectMethods ---@generic RT ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param regionType `RT` | "FontString" | "Texture" | "EditBox" | "ScrollingMessageFrame" | FrameType ---@param regionName string ---@param parentRegion Diesal.GUI.Parent.Region ---@param defaultFontObject? Font ---@param ... any ---@return RT CreateRegion = function(self, regionType, regionName, parentRegion, defaultFontObject, ...) if regionType == "FontString" then ---@class Diesal.GUI.Region.FontString local fontString = parentRegion:CreateFontString() fontString.defaultFontObject = defaultFontObject or _G.DiesalFontNormal fontString:SetFont(fontString.defaultFontObject:GetFont()) fontString:SetTextColor(fontString.defaultFontObject:GetTextColor()) fontString:SetSpacing(fontString.defaultFontObject:GetSpacing()) self[regionName] = fontString self.fontStrings[regionName] = fontString return fontString end if regionType == "Texture" then self[regionName] = parentRegion:CreateTexture(...) return self[regionName] end if regionType == "EditBox" then local editBox = CreateFrame("EditBox", nil, parentRegion, ...) ---@cast editBox Diesal.GUI.Region.EditBox -- set Default font properties editBox.defaultFontObject = defaultFontObject or _G.DiesalFontNormal editBox:SetFont(editBox.defaultFontObject:GetFont()) editBox:SetTextColor(editBox.defaultFontObject:GetTextColor()) editBox:SetSpacing(editBox.defaultFontObject:GetSpacing()) editBox:HookScript("OnEscapePressed", function(this) DiesalGUI:ClearFocus() end) editBox:HookScript("OnEditFocusGained", function(this) DiesalGUI:SetFocus(this) GameTooltip:Hide() end) self[regionName] = editBox return editBox end if regionType == "ScrollingMessageFrame" then local srollingMessageFrame = CreateFrame("ScrollingMessageFrame", nil, parentRegion, ...) ---@cast srollingMessageFrame Diesal.GUI.Region.ScrollingMessageFrame -- set Default font properties srollingMessageFrame.defaultFontObject = defaultFontObject or _G.DiesalFontNormal srollingMessageFrame:SetFont(srollingMessageFrame.defaultFontObject:GetFont()) srollingMessageFrame:SetTextColor(srollingMessageFrame.defaultFontObject:GetTextColor()) srollingMessageFrame:SetSpacing(srollingMessageFrame.defaultFontObject:GetSpacing()) self[regionName] = srollingMessageFrame return srollingMessageFrame end self[regionName] = CreateFrame(regionType, nil, parentRegion, ...) return self[regionName] end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param methods? table SetMethods = function(self, methods) if methods and type(methods) == "table" then for method, func in pairs(methods) do if type(func) == "function" then self.methods[method] = func end end end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ResetFonts = function(self) for name, fontString in pairs(self.fontStrings) do fontString:SetFont(fontString.defaultFontObject:GetFont()) fontString:SetTextColor(fontString.defaultFontObject:GetTextColor()) fontString:SetSpacing(fontString.defaultFontObject:GetSpacing()) end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param object Diesal.Object AddChild = function(self, object) tinsert(self.children, object) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase Release = function(self) DiesalGUI:Release(self) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param object Diesal.Object ReleaseChild = function(self, object) local children = self.children for i = 1, #children do if children[i] == object then children[i]:Release() tremove(children, i) break end end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ReleaseChildren = function(self) local children = self.children for i = 1, #children do children[i]:Release() children[i] = nil end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param parent? Diesal.Object SetParentObject = function(self, parent) local frame = self.frame local settings = self.settings frame:SetParent(nil) if parent then frame:SetParent(parent.content) settings.parent = parent.content end settings.parentObject = parent end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param settings table ---@param apply? boolean SetSettings = function(self, settings, apply) for key, value in pairs(settings) do self.settings[key] = value end if apply then self:ApplySettings() end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param apply? boolean ResetSettings = function(self, apply) self.settings = DiesalTools.TableCopy(self.defaults or {}) if apply then self:ApplySettings() end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param event string FireEvent = function(self, event, ...) if self.eventListeners[event] then for _, listner in ipairs(self.eventListeners[event]) do listner(self, event, ...) end --return self.eventListeners[event](self, event, ...) end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param event string ---@param listener fun(self: T, event: string, ...: any) AddEventListener = function(self, event, listener) if type(listener) == "function" then --self.eventListeners[event] = listener if not self.eventListeners[event] then self.eventListeners[event] = {} end table.insert(self.eventListeners[event], listener) else error("listener is required to be a function", 2) end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param event string ---@param listener fun(self: T, event: string, ...: any) SetEventListener = function(self, event, listener) if type(listener) == "function" then --self.eventListeners[event] = listener if not self.eventListeners[event] then self.eventListeners[event] = {} end table.insert(self.eventListeners[event], listener) else error("listener is required to be a function", 2) end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ResetEventListeners = function(self) for k in pairs(self.eventListeners) do self.eventListeners[k] = nil end end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param name string ---@param style Diesal.Style.Style SetStyle = function(self, name, style) DiesalStyle:SetObjectStyle(self, name, style) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param name string ---@param style Diesal.Style.Style UpdateStyle = function(self, name, style) DiesalStyle:UpdateObjectStyle(self, name, style) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param Stylesheet Diesal.Style.Stylesheet UpdateStylesheet = function(self, Stylesheet) DiesalStyle:UpdateObjectStylesheet(self, Stylesheet) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param Stylesheet Diesal.Style.Stylesheet SetStylesheet = function(self, Stylesheet) DiesalStyle:SetObjectStylesheet(self, Stylesheet) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ---@param name string ReleaseTexture = function(self, name) if not self.textures[name] then return end DiesalStyle:ReleaseTexture(self, name) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ReleaseTextures = function(self) DiesalStyle:ReleaseTextures(self) end, ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase ApplySettings = function(self) end, --#endregion DiesalObjectMethods --#endregion Diesal.GUI.Objectbase.BaseMethods } DiesalGUI.ObjectBase = ObjectBase ---@class Diesal.GUI.ObjectBase.Settings ---@field parent Frame ---@field parentObject Diesal.Object? ---@field height number ---@field width number ---@class Diesal.GUI.ObjectBase.Methods ---@field OnAcquire fun() ---@field OnRelease fun() ---@field ApplySettings fun(self) ---@alias DiesalObjectBase Diesal.GUI.ObjectBase -- Returns an Object Base ---@param objectType string | Diesal.Object.Type local Constructor = function(objectType) ---@class Diesal.GUI.ObjectBase : Diesal.GUI.ObjectBase.Methods ---@field frame Frame ---@field isContainer boolean ---@field type Diesal.Object.Type ---@field fontStrings { [string]: Diesal.GUI.Region.FontString } ---@field textures { [string]: Diesal.Style.Texture } ---@field children { [number]: Diesal.GUI.ObjectBase } ---@field eventListeners { [string]: fun(self: self, event: string, ...)[] } ---@field settings Diesal.GUI.ObjectBase.Settings ---@field defaults Diesal.GUI.ObjectBase.Settings local object = { isContainer = false, type = objectType, fontStrings = {}, textures = {}, children = {}, eventListeners = {}, methods = {}, } for k, v in pairs(ObjectBase) do object.methods[k] = v end setmetatable(object, { ---@param self Diesal.GUI.ObjectBase __index = function(self, k) local response = rawget(object, k) if response ~= nil then return response end -- Look for replaced methods. response = object.methods[k] if response ~= nil then return response end return rawget(object, k) end, }) return object end DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version) --[[ function DiesalGUI:CreateObjectBase(objectType) local object = { isContainer = false, type = objectType, fontStrings = {}, textures = {}, children = {}, eventListeners = {}, } setmetatable(object, { __index = ObjectBase }) return object end ]]