---@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 Colors = DiesalStyle.Colors -- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local type, select, pairs, tonumber = type, select, pairs, tonumber local floor, ceil = math.floor, math.ceil -- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- | Window |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local Type = "DiesalWindow" local Version = 14 -- ~~| Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local Stylesheet = { ["frame-outline"] = { type = "outline", layer = "BACKGROUND", color = "000000", }, ["frame-shadow"] = { type = "shadow", edgeSize = 0, offset = { 5, 5, 5, 5}, edgeFile = [[interface/reforging/itemupgradefxtooltipglow]], }, ["titleBar-color"] = { type = "texture", layer = "BACKGROUND", color = "000000", alpha = 0.95, }, ["titletext-Font"] = { type = "font", color = "d8d8d8", }, ["header-background"] = { type = "texture", layer = "BACKGROUND", gradient = { "VERTICAL", Colors.UI_400_GR[1], Colors.UI_400_GR[2] }, alpha = 0.95, position = { 0, 0, 0, -1 }, }, ["header-inline"] = { type = "outline", layer = "BORDER", gradient = { "VERTICAL", "ffffff", "ffffff" }, alpha = { 0.05, 0.02 }, position = { 0, 0, 0, -1 }, }, ["header-divider"] = { type = "texture", layer = "BORDER", color = "000000", alpha = 1, position = { 0, 0, nil, 0 }, height = 1, }, ["content-background"] = { type = "texture", layer = "BACKGROUND", color = Colors.UI_100, alpha = 0.95, }, ["content-outline"] = { type = "outline", layer = "BORDER", color = "FFFFFF", alpha = 0.01, }, ["footer-background"] = { type = "texture", layer = "BACKGROUND", gradient = { "VERTICAL", Colors.UI_400_GR[1], Colors.UI_400_GR[2] }, alpha = 0.95, position = { 0, 0, -1, 0 }, }, ["footer-divider"] = { type = "texture", layer = "BACKGROUND", color = "000000", position = { 0, 0, 0, nil }, height = 1, }, ["footer-inline"] = { type = "outline", layer = "BORDER", gradient = { "VERTICAL", "ffffff", "ffffff" }, alpha = { 0.05, 0.02 }, position = { 0, 0, -1, 0 }, debug = true, }, } local wireFrame = { ["frame-white"] = { type = "outline", layer = "OVERLAY", color = "ffffff", }, ["titleBar-yellow"] = { type = "outline", layer = "OVERLAY", color = "fffc00", }, ["closeButton-orange"] = { type = "outline", layer = "OVERLAY", color = "ffd400", }, ["header-blue"] = { type = "outline", layer = "OVERLAY", color = "00aaff", }, ["footer-green"] = { type = "outline", layer = "OVERLAY", color = "55ff00", }, } local sizerWireFrame = { ["sizerR-yellow"] = { type = "outline", layer = "OVERLAY", color = "fffc00", }, ["sizerB-green"] = { type = "outline", layer = "OVERLAY", color = "55ff00", }, ["sizerBR-blue"] = { type = "outline", layer = "OVERLAY", color = "00aaff", }, } -- | Window Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local function round(num) if num >= 0 then return floor(num + 0.5) else return ceil(num - 0.5) end end -- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ---@class Diesal.GUI.Window.Methods ---@field OnAcquire fun(self: Diesal.GUI.Object.Window) ---@field OnRelease fun(self: Diesal.GUI.Object.Window) ---@field SetTopLevel fun(self: Diesal.GUI.Object.Window) ---@field SetContentHeight fun(self: Diesal.GUI.Object.Window, height: number) ---@field ApplySettings fun(self: Diesal.GUI.Object.Window) ---@field UpdatePosition fun(self: Diesal.GUI.Object.Window) ---@field UpdateSizers fun(self: Diesal.GUI.Object.Window) ---@field SetTitle fun(self: Diesal.GUI.Object.Window, title?: string, subtitle?: string) local methods = { ---@param self Diesal.GUI.Object.Window ["OnAcquire"] = function(self) self:ApplySettings() self:SetStylesheet(Stylesheet) -- self:SetStylesheet(sizerWireFrame) self:Show() end, ["OnRelease"] = function(self) end, ["SetTopLevel"] = function(self) self.frame:SetToplevel(true) end, ---@param height number ["SetContentHeight"] = function(self, height) local contentHeight = round(self.content:GetHeight()) self.frame:SetHeight((self.settings.height - contentHeight) + height) end, ["ApplySettings"] = function(self) local settings = self.settings local frame = self.frame local titleBar = self.titleBar local closeButton = self.closeButton local header = self.header local content = self.content local footer = self.footer local headerHeight = settings.header and settings.headerHeight or 0 local footerHeight = settings.footer and settings.footerHeight or 0 frame:SetResizeBounds(settings.minWidth, settings.minHeight, settings.maxWidth, settings.maxHeight) self:UpdatePosition() self:UpdateSizers() titleBar:SetHeight(settings.titleBarHeight) closeButton:SetHeight(settings.titleBarHeight - 6) closeButton:SetWidth(settings.titleBarHeight - 6) content:SetPoint("TOPLEFT", settings.padding[1], -(settings.titleBarHeight + headerHeight + settings.padding[3])) content:SetPoint("BOTTOMRIGHT", -settings.padding[2], footerHeight + settings.padding[4]) header:SetHeight(headerHeight) footer:SetHeight(footerHeight) header[settings.header and "Show" or "Hide"](header) footer[settings.footer and "Show" or "Hide"](footer) header:SetPoint("TOPLEFT", self.titleBar, "BOTTOMLEFT", settings.padding[1], 0) header:SetPoint("TOPRIGHT", self.titleBar, "BOTTOMRIGHT", -settings.padding[2], 0) footer:SetPoint("BOTTOMLEFT", settings.padding[1], settings.padding[4]) footer:SetPoint("BOTTOMRIGHT", -settings.padding[2], settings.padding[4]) end, ["UpdatePosition"] = function(self) self.frame:ClearAllPoints() if self.settings.top and self.settings.left then self.frame:SetPoint("TOP", UIParent, "BOTTOM", 0, self.settings.top) self.frame:SetPoint("LEFT", UIParent, "LEFT", self.settings.left, 0) else self.frame:SetPoint("CENTER", UIParent, "CENTER") end self.frame:SetWidth(self.settings.width) self.frame:SetHeight(self.settings.height) end, ["UpdateSizers"] = function(self) local settings = self.settings local frame = self.frame local sizerB = self.sizerB local sizerR = self.sizerR local sizerBR = self.sizerBR sizerBR[settings.sizerBR and "Show" or "Hide"](sizerBR) sizerBR:SetSize(settings.sizerBRWidth, settings.sizerBRHeight) sizerB[settings.sizerB and "Show" or "Hide"](sizerB) sizerB:SetHeight(settings.sizerHeight) sizerB:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -settings.sizerBRWidth, 0) sizerR[settings.sizerR and "Show" or "Hide"](sizerR) sizerR:SetWidth(settings.sizerWidth) sizerR:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -settings.titleBarHeight) sizerR:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, settings.sizerBRHeight) end, ---@param title string ---@param subtitle? string ["SetTitle"] = function(self, title, subtitle) local settings = self.settings settings.title = title or settings.title settings.subTitle = subtitle or settings.subTitle self.titletext:SetText(("%s |cff7f7f7f%s"):format(settings.title, settings.subTitle)) end, } ---@alias PaddingLeft number ---@alias PaddingRight number ---@alias PaddingTop number ---@alias PaddingBottom number ---@class Diesal.GUI.Window.Settings ---@field footer boolean -- false ---@field footerHeight number -- 21 ---@field header boolean -- false ---@field headerHeight number -- 21 ---@field height number -- 300 ---@field left? number ---@field maxHeight number -- 9999 ---@field maxWidth number -- 9999 ---@field minHeight number -- 200 ---@field minWidth number -- 200 ---@field padding { [1]: PaddingLeft, [2]: PaddingRight, [3]: PaddingTop, [4]: PaddingBottom } -- Left, Right, Top, Bottom ---@field sizerB boolean -- true ---@field sizerBR boolean -- true ---@field sizerBRHeight number -- 6, ---@field sizerBRWidth number -- 6, ---@field sizerHeight number -- 6 ---@field sizerR boolean -- true ---@field sizerWidth number -- 6 ---@field subTitle string -- "" ---@field title string -- "" ---@field titleBarHeight number -- 18, ---@field top? number ---@field width number -- 500, ---@class DiesalWindow : Diesal.GUI.Object.Window -- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local function Constructor() ---@class Diesal.GUI.Object.Window : Diesal.GUI.ObjectBase, Diesal.GUI.Window.Methods ---@field frame Frame ---@field titleBar Button ---@field closeButton Button ---@field titletext FontString ---@field header Frame ---@field content Frame ---@field footer Frame ---@field sizerR Frame ---@field sizerB Frame ---@field sizerBR Frame ---@field listener Tinkr.Util.GUIBuilder.Listener ---@field status_listener Tinkr.Util.GUIBuilder.Listener ---@field settings Diesal.GUI.Window.Settings ---@field defaults Diesal.GUI.Window.Settings local self = DiesalGUI:Create(Type, true) self.isContainer = true local frame = CreateFrame("Frame", nil, DiesalGUI.UIParent) frame:SetClampedToScreen(true) self.frame = frame self.defaults = { height = 300, width = 500, minHeight = 200, minWidth = 200, maxHeight = 9999, maxWidth = 9999, left = nil, top = nil, titleBarHeight = 18, title = "", subTitle = "", padding = { 1, 1, 0, 1 }, header = false, headerHeight = 21, footer = false, footerHeight = 21, sizerR = true, sizerB = true, sizerBR = true, sizerWidth = 6, sizerHeight = 6, sizerBRHeight = 6, sizerBRWidth = 6, } -- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- OnAcquire, OnRelease, OnHeightSet, OnWidthSet -- OnSizeChanged, OnDragStop, OnHide, OnShow, OnClose -- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ frame:EnableMouse() frame:SetMovable(true) frame:SetResizable(true) frame:SetScript("OnMouseDown", function(this, button) DiesalGUI:OnMouse(this, button) end) frame:SetScript("OnSizeChanged", function(this, width, height) self.settings.width = DiesalTools.Round(width) self.settings.height = DiesalTools.Round(height) self:FireEvent("OnSizeChanged", self.settings.width, self.settings.height) end) frame:SetScript("OnHide", function(this) self:FireEvent("OnHide") end) frame:SetScript("OnShow", function(this) self:FireEvent("OnShow") end) frame:SetToplevel(true) local titleBar = self:CreateRegion("Button", "titleBar", frame) titleBar:SetPoint("TOPLEFT") titleBar:SetPoint("TOPRIGHT") titleBar:EnableMouse() titleBar:SetScript("OnMouseDown", function(this, button) DiesalGUI:OnMouse(this, button) frame:StartMoving() end) titleBar:SetScript("OnMouseUp", function(this) frame:StopMovingOrSizing() self.settings.top = DiesalTools.Round(frame:GetTop()) self.settings.left = DiesalTools.Round(frame:GetLeft()) self:UpdatePosition() self:FireEvent("OnDragStop", self.settings.left, self.settings.top) end) local closeButton = self:CreateRegion("Button", "closeButton", titleBar) closeButton:SetNormalAtlas("uitools-icon-close") closeButton:SetHighlightAtlas("uitools-icon-close") closeButton:GetHighlightTexture():SetVertexColor(1, 0, 0, 1) --closeButton:SetPushedAtlas("simplecheckout-close-pressed-1x") --closeButton:GetHighlightTexture():SetVertexColor(1, 0, 0, 1) closeButton:SetScript("OnEnter",function() closeButton:GetNormalTexture():Hide() end) closeButton:SetScript("OnLeave", function() closeButton:GetNormalTexture():Show() end) closeButton:SetPoint("RIGHT", -5, -0) closeButton:SetScript("OnClick", function(this, button) DiesalGUI:OnMouse(this, button) PlaySound(799) self:FireEvent("OnClose") self:Hide() end) local titletext = self:CreateRegion("FontString", "titletext", titleBar) titletext:SetWordWrap(false) titletext:SetPoint("LEFT", 4, 0) titletext:SetPoint("RIGHT", -20, 0) titletext:SetJustifyH("LEFT") self:CreateRegion("Frame", "header", frame) self:CreateRegion("Frame", "content", frame) self:CreateRegion("Frame", "footer", frame) local sizerBR = self:CreateRegion("Frame", "sizerBR", frame) sizerBR:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0) sizerBR:EnableMouse() sizerBR:SetScript("OnMouseDown", function(this, button) DiesalGUI:OnMouse(this, button) frame:StartSizing("BOTTOMRIGHT") end) sizerBR:SetScript("OnMouseUp", function(this) frame:StopMovingOrSizing() self:UpdatePosition() self:FireEvent("OnSizeStop", self.settings.width, self.settings.height) end) local sizerB = self:CreateRegion("Frame", "sizerB", frame) sizerB:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, 0) sizerB:EnableMouse() sizerB:SetScript("OnMouseDown", function(this, button) DiesalGUI:OnMouse(this, button) frame:StartSizing("BOTTOM") end) sizerB:SetScript("OnMouseUp", function(this) frame:StopMovingOrSizing() self:UpdatePosition() self:FireEvent("OnSizeStop", self.settings.width, self.settings.height) end) local sizerR = self:CreateRegion("Frame", "sizerR", frame) sizerR:EnableMouse() sizerR:SetScript("OnMouseDown", function(this, button) DiesalGUI:OnMouse(this, button) frame:StartSizing("RIGHT") end) sizerR:SetScript("OnMouseUp", function(this) frame:StopMovingOrSizing() self:UpdatePosition() self:FireEvent("OnSizeStop", self.settings.width, self.settings.height) end) -- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self:SetMethods(methods) self:SetObj(self.frame) --[[ for method, func in pairs(methods) do self[method] = func end ]] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return self end DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)