You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
12 KiB

---@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")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sub, format, match, lower = string.sub, string.format, string.match, string.lower
local tsort = table.sort
local tostring = tostring
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| TableExplorerBranch |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalBranch"
local Version = 1
-- ~~| Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["button-highlight"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.1,
},
["button-selected"] = {
type = "texture",
layer = "BORDER",
color = "0059b3",
alpha = 0,
},
}
local wireFrameSheet = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["button-purple"] = {
type = "outline",
layer = "OVERLAY",
color = "aa00ff",
},
["content-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "fffc00",
},
}
-- ~~| Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Branch.Methods
---@field OnAcquire fun(self: Diesal.GUI.Object.Branch)
---@field OnRelease fun(self: Diesal.GUI.Object.Branch)
---@field ApplySettings fun(self: Diesal.GUI.Object.Branch): boolean | nil
---@field Collapse fun(self: Diesal.GUI.Object.Branch)
---@field Expand fun(self: Diesal.GUI.Object.Branch)
---@field UpdateHeight fun(self: Diesal.GUI.Object.Branch)
---@field SetLabel fun(self: Diesal.GUI.Object.Branch, text: string)
---@field SetIconTexture fun(self: Diesal.GUI.Object.Branch, texture: string)
---@field SetIconCoords fun(self: Diesal.GUI.Object.Branch, left: number, right: number, top: number, bottom: number)
---@field SetIconExpanded fun(self: Diesal.GUI.Object.Branch)
---@field SetIconCollapsed fun(self: Diesal.GUI.Object.Branch)
---@field SetSelected fun(self: Diesal.GUI.Object.Branch, state: boolean)
---@field UpdateLines fun(self: Diesal.GUI.Object.Branch)
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
if not self.settings.position then
return false
end
local button = self.button
local content = self.content
button:SetHeight(self.settings.buttonHeight)
if not self.settings.leaf then
self[self.settings.expanded and "Expand" or "Collapse"](self)
else
self:UpdateLines()
self:UpdateHeight()
end
self:ClearAllPoints()
if self.settings.position == 1 then
self:SetPoint("TOPLEFT", self.settings.indent, 0)
self:SetPoint("RIGHT")
else
local anchor = self.settings.parentObject.children[self.settings.position - 1].frame
self:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, 0)
self:SetPoint("RIGHT")
end
end,
["Collapse"] = function(self)
if self.settings.leaf then
return
end
self:FireEvent("OnStateChange", false)
self.settings.expanded = false
self:SetIconCollapsed()
self:UpdateLines()
self.content:Hide()
self:UpdateHeight()
end,
["Expand"] = function(self)
if self.settings.leaf then
return
end
self:FireEvent("OnStateChange", true)
self.settings.expanded = true
self:SetIconExpanded()
self:UpdateLines()
self.content:Show()
self:UpdateHeight()
end,
["UpdateHeight"] = function(self)
local contentHeight = 0
local settings = self.settings
local children = self.children
if settings.expanded then
for i = 1, #children do
contentHeight = contentHeight + children[i].frame:GetHeight()
end
end
self.content:SetHeight(contentHeight)
self:SetHeight(settings.buttonHeight + contentHeight)
settings.parentObject:UpdateHeight()
end,
["SetLabel"] = function(self, text)
self.text:SetText(text)
end,
["SetIconTexture"] = function(self, texture)
self.icon:SetTexture(texture)
end,
["SetIconCoords"] = function(self, left, right, top, bottom)
self.icon:SetTexCoord(left, right, top, bottom)
end,
["SetIconExpanded"] = function(self)
self.icon:SetTexCoord(DiesalTools.GetIconCoords(2, 8, 16, 256, 128))
end,
["SetIconCollapsed"] = function(self)
self.icon:SetTexCoord(DiesalTools.GetIconCoords(1, 8, 16, 256, 128))
end,
["SetSelected"] = function(self, state)
self:UpdateStyle("button-selected", {
type = "texture",
alpha = state and 1 or 0,
})
end,
["UpdateLines"] = function(self)
if not self.settings.branches then
return
end
local foldColor = "353535"
local expandColor = "5a5a5a"
-- Frame Fold Line
if not self.settings.last and not self.settings.leaf then
self:UpdateStyle("frame-foldLine", {
type = "texture",
layer = "OVERLAY",
color = foldColor,
position = { 6, nil, -11, 2 },
width = 1,
})
end
-- expandable Fold Lines
if not self.settings.leaf then
self:UpdateStyle("button-square", {
type = "outline",
layer = "BORDER",
color = foldColor,
position = { 10, nil, -2, nil },
width = 9,
height = 9,
})
self:UpdateStyle("button-expandH", {
type = "texture",
layer = "BORDER",
color = expandColor,
position = { 8, nil, -6, nil },
width = 5,
height = 1,
})
self:UpdateStyle("button-expandV", {
type = "texture",
layer = "BORDER",
color = expandColor,
position = { 6, nil, -4, nil },
width = 1,
height = 5,
alpha = 1,
})
if self.settings.expanded then
self:UpdateStyle("button-expandV", {
type = "texture",
alpha = 0,
})
end
else -- Leaf nodes
self:UpdateStyle("button-lineV", {
type = "texture",
layer = "BORDER",
color = foldColor,
position = { 6, nil, -6, nil },
height = 1,
width = 6,
})
self:UpdateStyle("button-lineH", {
type = "texture",
layer = "BORDER",
color = foldColor,
position = { 6, nil, 0, 0 },
width = 1,
})
if self.settings.last then
self:UpdateStyle("button-lineH", {
type = "texture",
position = { 6, nil, 0, -7 },
})
end
end
end,
}
---@class DiesalBranch : Diesal.GUI.Object.Branch
---@class Diesal.GUI.Object.Branch.Settings.Default
---@field fontObject Font
---@field branches boolean
---@field expanded boolean
---@field buttonHeight number
---@field indent number
---@field expIconTex string
---@field colIconTex string
---@field expIconCoords {[1]: number, [2]: number, [3]: number, [4]: number }
---@field colIconCoords {[1]: number, [2]: number, [3]: number, [4]: number }
---@class Diesal.GUI.Object.Branch.Settings : Diesal.GUI.Object.Branch.Settings.Default
---@field parentObject Diesal.GUI.Object.Accordian.Section
---@field last boolean
---@field position number
---@field leaf boolean
-- ~~| TableExplorerBranch Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Branch : Diesal.GUI.ObjectBase, Diesal.GUI.Branch.Methods
---@field button Button
---@field icon Texture
---@field text Diesal.GUI.Region.FontString
---@field content Frame
---@field defaults Diesal.GUI.Object.Branch.Settings.Default
---@field settings Diesal.GUI.Object.Branch.Settings
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, DiesalGUI.UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
fontObject = DiesalFontNormal,
branches = true,
expanded = true,
buttonHeight = 14,
indent = 13,
expIconTex = "DiesalGUIcons",
colIconTex = "DiesalGUIcons",
expIconCoords = { DiesalTools.GetIconCoords(2, 8, 16, 256, 128) },
colIconCoords = { DiesalTools.GetIconCoords(1, 8, 16, 256, 128) },
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local button = self:CreateRegion("Button", "button", frame)
button:SetPoint("TOPRIGHT")
button:SetPoint("TOPLEFT")
button:RegisterForClicks("RightButtonUp", "LeftButtonUp")
button:RegisterForDrag("LeftButton")
---@param this Button
---@param button mouseButton
button:SetScript("OnClick", function(this, button)
DiesalGUI:OnMouse(this, button)
if button == "LeftButton" then
self[not self.settings.expanded and "Expand" or "Collapse"](self)
end
self:FireEvent("OnClick", button)
end)
---@param this Button
button:SetScript("OnDoubleClick", function(this, ...)
self:FireEvent("OnDoubleClick", ...)
end)
---@param this Button
button:SetScript("OnDragStart", function(this, ...)
self:FireEvent("OnDragStart", ...)
end)
---@param this Button
button:SetScript("OnDragStop", function(this, ...)
self:FireEvent("OnDragStop", ...)
end)
---@param this Button
button:SetScript("OnEnter", function(this, ...)
self:FireEvent("OnEnter", ...)
end)
---@param this Button
button:SetScript("OnLeave", function(this, ...)
self:FireEvent("OnLeave", ...)
end)
local icon = self:CreateRegion("Texture", "icon", button)
DiesalStyle:StyleTexture(icon, {
type = "texture",
position = { 0, nil, 2, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons" },
})
local text = self:CreateRegion("FontString", "text", button)
text:SetPoint("TOPLEFT", 14, -1)
text:SetPoint("BOTTOMRIGHT", -4, 0)
text:SetHeight(0)
--text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local content = self:CreateRegion("Frame", "content", button)
content:SetPoint("TOPLEFT", button, "BOTTOMLEFT", 0, 0)
content:SetPoint("TOPRIGHT")
content:SetHeight(0)
-- ~~ 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)