2.0 Update.

main
ck 1 year ago
parent 2c1766968b
commit c524708bd6
  1. 8
      .gitignore
  2. 384
      DiesalLibs/DiesalGUI-1.0/DiesalGUI-1.0.lua
  3. 23
      DiesalLibs/DiesalGUI-1.0/DiesalGUI-1.0.xml
  4. 62
      DiesalLibs/DiesalGUI-1.0/Objects/Accordian.lua
  5. 217
      DiesalLibs/DiesalGUI-1.0/Objects/AccordianSection.lua
  6. 177
      DiesalLibs/DiesalGUI-1.0/Objects/Bar.lua
  7. 279
      DiesalLibs/DiesalGUI-1.0/Objects/Branch.lua
  8. 109
      DiesalLibs/DiesalGUI-1.0/Objects/Button.lua
  9. 163
      DiesalLibs/DiesalGUI-1.0/Objects/CheckBox.lua
  10. 282
      DiesalLibs/DiesalGUI-1.0/Objects/ComboBox.lua
  11. 122
      DiesalLibs/DiesalGUI-1.0/Objects/ComboBoxItem.lua
  12. 296
      DiesalLibs/DiesalGUI-1.0/Objects/DropDown.lua
  13. 137
      DiesalLibs/DiesalGUI-1.0/Objects/DropDownItem.lua
  14. 124
      DiesalLibs/DiesalGUI-1.0/Objects/Input.lua
  15. 163
      DiesalLibs/DiesalGUI-1.0/Objects/QuickDoc.lua
  16. 279
      DiesalLibs/DiesalGUI-1.0/Objects/ScrollFrame.lua
  17. 279
      DiesalLibs/DiesalGUI-1.0/Objects/ScrollingEditBox.lua
  18. 267
      DiesalLibs/DiesalGUI-1.0/Objects/ScrollingMessageFrame.lua
  19. 294
      DiesalLibs/DiesalGUI-1.0/Objects/Spinner.lua
  20. 174
      DiesalLibs/DiesalGUI-1.0/Objects/Toggle.lua
  21. 93
      DiesalLibs/DiesalGUI-1.0/Objects/Tree.lua
  22. 387
      DiesalLibs/DiesalGUI-1.0/Objects/Window.lua
  23. 360
      DiesalLibs/DiesalGUI-2.0/DiesalGUI-2.0.lua
  24. 25
      DiesalLibs/DiesalGUI-2.0/DiesalGUI-2.0.xml
  25. 82
      DiesalLibs/DiesalGUI-2.0/Objects/Accordian.lua
  26. 264
      DiesalLibs/DiesalGUI-2.0/Objects/AccordianSection.lua
  27. 205
      DiesalLibs/DiesalGUI-2.0/Objects/Bar.lua
  28. 341
      DiesalLibs/DiesalGUI-2.0/Objects/Branch.lua
  29. 127
      DiesalLibs/DiesalGUI-2.0/Objects/Button.lua
  30. 190
      DiesalLibs/DiesalGUI-2.0/Objects/CheckBox.lua
  31. 314
      DiesalLibs/DiesalGUI-2.0/Objects/ComboBox.lua
  32. 145
      DiesalLibs/DiesalGUI-2.0/Objects/ComboBoxItem.lua
  33. 404
      DiesalLibs/DiesalGUI-2.0/Objects/DropDown.lua
  34. 171
      DiesalLibs/DiesalGUI-2.0/Objects/DropDownItem.lua
  35. 131
      DiesalLibs/DiesalGUI-2.0/Objects/Input.lua
  36. 479
      DiesalLibs/DiesalGUI-2.0/Objects/ObjectBase.lua
  37. 151
      DiesalLibs/DiesalGUI-2.0/Objects/QuickDoc.lua
  38. 317
      DiesalLibs/DiesalGUI-2.0/Objects/ScrollFrame.lua
  39. 293
      DiesalLibs/DiesalGUI-2.0/Objects/ScrollingEditBox.lua
  40. 283
      DiesalLibs/DiesalGUI-2.0/Objects/ScrollingMessageFrame.lua
  41. 345
      DiesalLibs/DiesalGUI-2.0/Objects/Spinner.lua
  42. 43
      DiesalLibs/DiesalGUI-2.0/Objects/Text.lua
  43. 245
      DiesalLibs/DiesalGUI-2.0/Objects/Toggle.lua
  44. 104
      DiesalLibs/DiesalGUI-2.0/Objects/Tree.lua
  45. 462
      DiesalLibs/DiesalGUI-2.0/Objects/Window.lua
  46. 69
      DiesalLibs/DiesalMenu-1.0/DiesalMenu-1.0.lua
  47. 6
      DiesalLibs/DiesalMenu-1.0/DiesalMenu-1.0.xml
  48. 132
      DiesalLibs/DiesalMenu-1.0/Objects/Menu.lua
  49. 157
      DiesalLibs/DiesalMenu-1.0/Objects/MenuItem.lua
  50. 93
      DiesalLibs/DiesalMenu-2.0/DiesalMenu-2.0.lua
  51. 7
      DiesalLibs/DiesalMenu-2.0/DiesalMenu-2.0.xml
  52. 151
      DiesalLibs/DiesalMenu-2.0/Objects/Menu.lua
  53. 184
      DiesalLibs/DiesalMenu-2.0/Objects/MenuItem.lua
  54. 1048
      DiesalLibs/DiesalStyle-1.0/DiesalStyle-1.0.lua
  55. 1681
      DiesalLibs/DiesalStyle-2.0/DiesalStyle-2.0.lua
  56. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/DejaVuSansMono-Bold.ttf
  57. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/DejaVuSansMono.ttf
  58. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/FFF Intelligent Thin Condensed.ttf
  59. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/FiraMono-Bold.ttf
  60. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/FiraMono-Medium.ttf
  61. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/FiraMono-Regular.ttf
  62. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/FiraSans-Regular.ttf
  63. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/Hack-Bold.ttf
  64. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/Hack-Regular.ttf
  65. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/Inconsolata-Bold.ttf
  66. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/Inconsolata-Regular.ttf
  67. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/LUCON.TTF
  68. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/OfficeCodePro-Bold.ttf
  69. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/OfficeCodePro-Medium.ttf
  70. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/OfficeCodePro-Regular.ttf
  71. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/RobotoMono-Bold.ttf
  72. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/RobotoMono-Medium.ttf
  73. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/RobotoMono-Regular.ttf
  74. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/SourceCodePro-Black.ttf
  75. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/SourceCodePro-Bold.ttf
  76. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/SourceCodePro-Medium.ttf
  77. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/SourceCodePro-Regular.ttf
  78. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/SourceCodePro-Semibold.ttf
  79. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/Standard0755.ttf
  80. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/UbuntuMono-B.ttf
  81. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/UbuntuMono-R.ttf
  82. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/calibrib.ttf
  83. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/monof55.ttf
  84. 0
      DiesalLibs/DiesalStyle-2.0/Media/Fonts/monof56.ttf
  85. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/DiesalButtonIcons32x128x512.tga
  86. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/DiesalGUIcons16x256x128.tga
  87. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/DiesalGUIcons32x256x256.tga
  88. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/DiesalGUIcons64x256x256.tga
  89. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/shadow.tga
  90. 0
      DiesalLibs/DiesalStyle-2.0/Media/Textures/shadowNoDist.tga
  91. 515
      DiesalLibs/DiesalTools-1.0/DiesalTools-1.0.lua
  92. 581
      DiesalLibs/DiesalTools-2.0/DiesalTools-2.0.lua

8
.gitignore vendored

@ -40,4 +40,12 @@ luac.out
*.x86_64
*.hex
## Ignore mac files
.DS_Store
DS_Store
## whitelist .gitkeep files
!.gitkeep
## ignore all files in scripts

@ -1,384 +0,0 @@
-- $Id: DiesalGUI-1.0.lua 61 2017-03-28 23:13:41Z diesal2010 $
local MAJOR, MINOR = "DiesalGUI-1.0", "$Rev: 61 $"
local DiesalGUI, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalGUI then return end -- No Upgrade needed.
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CallbackHandler = LibStub("CallbackHandler-1.0")
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, tonumber = type, select, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local pairs, ipairs = pairs,ipairs
local tinsert, tremove = table.insert, table.remove
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent = CreateFrame, UIParent
-- ~~| DiesalGUI Values |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DiesalGUI.callbacks = DiesalGUI.callbacks or CallbackHandler:New(DiesalGUI)
DiesalGUI.ObjectFactory = DiesalGUI.ObjectFactory or {}
DiesalGUI.ObjectVersions = DiesalGUI.ObjectVersions or {}
DiesalGUI.ObjectPool = DiesalGUI.ObjectPool or {}
DiesalGUI.ObjectBase = DiesalGUI.ObjectBase or {}
-- ~~| DiesalGUI Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local ObjectFactory = DiesalGUI.ObjectFactory
local ObjectVersions = DiesalGUI.ObjectVersions
local ObjectPool = DiesalGUI.ObjectPool
local ObjectBase = DiesalGUI.ObjectBase
-- ~~| DiesalGUI Local Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function OnMouse(frame,button)
DiesalGUI:ClearFocus()
end
-- capture mouse clicks on the WorldFrame
local function WorldFrameOnMouse(frame,button)
OnMouse(frame,button)
end
_G.WorldFrame:HookScript("OnMouseDown", WorldFrameOnMouse )
-- Returns a new object
local function newObject(objectType)
if not ObjectFactory[objectType] then error("Attempt to construct unknown Object type", 2) end
ObjectPool[objectType] = ObjectPool[objectType] or {}
local newObj = next(ObjectPool[objectType])
if not newObj then
newObj = ObjectFactory[objectType](object)
else
ObjectPool[objectType][newObj] = nil
end
return newObj
end
-- Releases an object into ReleasedObjects
local function releaseObject(obj,objectType)
ObjectPool[objectType] = ObjectPool[objectType] or {}
if ObjectPool[objectType][obj] then
error("Attempt to Release Object that is already released", 2)
end
ObjectPool[objectType][obj] = true
end
-- ~~| Object Blizzard Base |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ObjectBase.Hide = function(self)
self.frame:Hide()
end
ObjectBase.Show = function(self)
self.frame:Show()
end
ObjectBase.SetParent = function(self, parent)
local frame = self.frame
frame:SetParent(nil)
frame:SetParent(parent)
self.settings.parent = parent
end
ObjectBase.SetWidth = function(self, width)
self.settings.width = width
self.frame:SetWidth(width)
self:FireEvent("OnWidthSet",width)
end
ObjectBase.SetHeight = function(self, height)
self.settings.height = height
self.frame:SetHeight(height)
self:FireEvent("OnHeightSet",height)
end
ObjectBase.SetSize = function(self, width, height)
self.settings.width = width
self.settings.height = height
self.frame:SetHeight(height)
self.frame:SetWidth(width)
self:FireEvent("OnWidthSet",width)
self:FireEvent("OnHeightSet",height)
end
ObjectBase.GetWidth = function(self)
return self.frame:GetWidth()
end
ObjectBase.GetHeight = function(self)
return self.frame:GetHeight()
end
ObjectBase.IsVisible = function(self)
return self.frame:IsVisible()
end
ObjectBase.IsShown = function(self)
return self.frame:IsShown()
end
ObjectBase.SetPoint = function(self, ...)
return self.frame:SetPoint(...)
end
ObjectBase.SetAllPoints = function(self, ...)
return self.frame:SetAllPoints(...)
end
ObjectBase.ClearAllPoints = function(self)
return self.frame:ClearAllPoints()
end
ObjectBase.GetNumPoints = function(self)
return self.frame:GetNumPoints()
end
ObjectBase.GetPoint = function(self, ...)
return self.frame:GetPoint(...)
end
-- ~~| Object Diesal Base |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ObjectBase.CreateRegion = function(self,regionType,regionName,parentRegion,defaultFontObject)
if regionType == 'FontString' then
local fontString = parentRegion:CreateFontString()
-- set Default font properties
if defaultFontObject then
fontString.defaultFontObject = defaultFontObject
else
fontString.defaultFontObject = DiesalFontNormal
end
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(regionType,nil,parentRegion)
-- set Default font properties
if defaultFontObject then
editBox.defaultFontObject = defaultFontObject
else
editBox.defaultFontObject = DiesalFontNormal
end
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(regionType,nil,parentRegion)
-- set Default font properties
if defaultFontObject then
srollingMessageFrame.defaultFontObject = defaultFontObject
else
srollingMessageFrame.defaultFontObject = DiesalFontNormal
end
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
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
ObjectBase.AddChild = function(self, object)
tinsert(self.children, object)
end
ObjectBase.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
ObjectBase.ReleaseChildren = function(self)
local children = self.children
for i = 1,#children do
children[i]:Release()
children[i] = nil
end
end
ObjectBase.Release = function(self)
DiesalGUI:Release(self)
end
ObjectBase.SetParentObject = function(self, parent)
local frame = self.frame
local settings = self.settings
frame:SetParent(nil)
frame:SetParent(parent.content)
settings.parent = parent.content
settings.parentObject = parent
end
ObjectBase.SetSettings = function(self,settings,apply)
for key,value in pairs(settings) do
self.settings[key] = value
end
if apply then self:ApplySettings() end
end
ObjectBase.ResetSettings = function(self,apply)
self.settings = DiesalTools.TableCopy( self.defaults )
if apply then self:ApplySettings() end
end
ObjectBase.SetEventListener = function(self, event, listener)
if type(listener) == "function" then
self.eventListeners[event] = listener
else
error("listener is required to be a function", 2)
end
end
ObjectBase.ResetEventListeners = function(self)
for k in pairs(self.eventListeners) do
self.eventListeners[k] = nil
end
end
ObjectBase.FireEvent = function(self, event, ...)
if self.eventListeners[event] then
return self.eventListeners[event]( self, event, ...)
end
end
ObjectBase.SetStyle = function(self,name,style)
DiesalStyle:SetObjectStyle(self,name,style)
end
ObjectBase.UpdateStyle = function(self,name,style)
DiesalStyle:UpdateObjectStyle(self,name,style)
end
ObjectBase.UpdateStylesheet = function(self,Stylesheet)
DiesalStyle:UpdateObjectStylesheet(self,Stylesheet)
end
ObjectBase.SetStylesheet = function(self,Stylesheet)
DiesalStyle:SetObjectStylesheet(self,Stylesheet)
end
ObjectBase.ReleaseTexture = function(self,name)
if not self.textures[name] then return end
DiesalStyle:ReleaseTexture(self,name)
end
ObjectBase.ReleaseTextures = function(self)
DiesalStyle:ReleaseTextures(self)
end
-- ~~| DiesalGUI API |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Returns an Object Base
function DiesalGUI:CreateObjectBase(Type)
local object = {
type = Type,
fontStrings = {},
textures = {},
children = {},
eventListeners = {},
}
setmetatable(object, {__index = ObjectBase})
return object
end
-- Registers an Object constructor in the ObjectFactory
function DiesalGUI:RegisterObjectConstructor(Type, constructor, version)
assert(type(constructor) == "function")
assert(type(version) == "number")
local oldVersion = ObjectVersions[Type]
if oldVersion and oldVersion >= version then return end
ObjectVersions[Type] = version
ObjectFactory[Type] = constructor
end
-- Create a new Object
function DiesalGUI:Create(objectType,name)
if ObjectFactory[objectType] then
local object
if name then -- needs a specific name, bypass the objectPool and create a new object
object = ObjectFactory[objectType](name)
else
object = newObject(objectType)
end
object:ResetSettings()
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if object.OnAcquire then object:OnAcquire() end
return object
end
end
function DiesalGUI:CreateThrottle(duration, callback)
assert(callback and type(callback) == 'function','callback has to be a function ')
assert(duration and type(duration) == 'number','duration has to be a number ')
local throttle = CreateFrame("Frame", nil, UIParent):CreateAnimationGroup()
throttle.anim = throttle:CreateAnimation("Animation")
throttle.args = {}
local mt = getmetatable(throttle)
mt.__index.SetCallback = function(self,callback)
assert(callback and type(callback) == 'function','callback required to be a function ')
self:SetScript("OnFinished", function() callback(unpack(self.args)) end)
end
mt.__index.AddCallback = function(self,callback)
assert(callback and type(callback) == 'function','callback required to be a function ')
self:HookScript("OnFinished", function() callback(unpack(self.args)) end)
end
mt.__index.SetDuration = function(self,duration)
assert(duration and type(duration) == 'number','duration has to be a number ')
self.anim:SetDuration(duration)
end
mt.__call = function(self,...)
self.args = {...}
self:Stop()
self:Play()
end
setmetatable(throttle,mt)
throttle:SetScript("OnFinished", function() callback(unpack(throttle.args)) end)
throttle:SetDuration(duration)
return throttle
end
-- Releases an object ready for reuse by Create
function DiesalGUI:Release(object)
if object.OnRelease then object:OnRelease() end
object:FireEvent("OnRelease")
object:ReleaseChildren()
object:ReleaseTextures()
object:ResetFonts()
object:ResetEventListeners()
object.frame:ClearAllPoints()
object.frame:Hide()
object.frame:SetParent(UIParent)
releaseObject(object, object.type)
end
-- Set FocusedObject: Menu, Dropdown, editBox etc....
function DiesalGUI:SetFocus(object)
if self.FocusedObject and self.FocusedObject ~= object then DiesalGUI:ClearFocus() end
self.FocusedObject = object
end
-- clear focus from the FocusedObject
function DiesalGUI:ClearFocus()
local FocusedObject = self.FocusedObject
if FocusedObject then
if FocusedObject.ClearFocus then -- FocusedObject is Focusable Frame
FocusedObject:ClearFocus()
end
self.FocusedObject = nil
end
end
-- Mouse Input capture for any DiesalGUI interactive region
function DiesalGUI:OnMouse(frame,button)
-- print(button)
OnMouse(frame,button)
DiesalGUI.callbacks:Fire("DiesalGUI_OnMouse", frame, button)
end
DiesalGUI.counts = DiesalGUI.counts or {}
--- A type-based counter to count the number of widgets created.
function DiesalGUI:GetNextObjectNum(type)
if not self.counts[type] then
self.counts[type] = 0
end
self.counts[type] = self.counts[type] + 1
return self.counts[type]
end
--- Return the number of created widgets for this type.
function DiesalGUI:GetObjectCount(type)
return self.counts[type] or 0
end

@ -1,23 +0,0 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="DiesalGUI-1.0.lua"/>
<!-- Objects -->
<Script file="Objects\Window.lua"/>
<Script file="Objects\ScrollFrame.lua"/>
<Script file="Objects\ScrollingEditBox.lua"/>
<Script file="Objects\ScrollingMessageFrame.lua"/>
<Script file="Objects\CheckBox.lua"/>
<Script file="Objects\Button.lua"/>
<Script file="Objects\Spinner.lua"/>
<Script file="Objects\Input.lua"/>
<Script file="Objects\Dropdown.lua"/>
<Script file="Objects\DropdownItem.lua"/>
<Script file="Objects\ComboBox.lua"/>
<Script file="Objects\ComboBoxItem.lua"/>
<Script file="Objects\Accordian.lua"/>
<Script file="Objects\AccordianSection.lua"/>
<Script file="Objects\Tree.lua"/>
<Script file="Objects\Branch.lua"/>
<Script file="Objects\Bar.lua"/>
<Script file="Objects\Toggle.lua"/>
</Ui>

@ -1,62 +0,0 @@
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Accordian |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "Accordian"
local Version = 2
-- ~~| Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
color = 'FF0000',
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
-- self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:ResetSettings(true)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
end,
['CollapseAll'] = function(self)
for i=1 , #self.children do
self.children[i]:Collapse()
end
end,
['ExpandAll'] = function(self)
for i=1 , #self.children do
self.children[i]:Expand()
end
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = { }
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHeightChange
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local content = self:CreateRegion("Frame", 'content', frame)
content:SetAllPoints()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,217 +0,0 @@
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | AccordianSection |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'AccordianSection'
local Version = 3
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['button-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_400_GR[1],Colors.UI_400_GR[2]},
alpha = .95,
position = {0,0,-1,0},
},
['button-outline'] = {
type = 'outline',
layer = 'BACKGROUND',
color = '000000',
position = {1,1,0,1},
},
['button-inline'] = {
type = 'outline',
layer = 'ARTWORK',
gradient = {'VERTICAL','ffffff','ffffff'},
alpha = {.03,.02},
position = {0,0,-1,0},
},
['button-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .1,
},
['button-leftExpandIcon'] = {
type = 'texture',
position = {0,nil,-1,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons',{3,6,16,256,128},HSL(Colors.UI_Hue,Colors.UI_Saturation,.65)},
alpha = 1,
},
['button-leftCollapseIcon'] = {
type = 'texture',
position = {0,nil,-1,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons',{4,6,16,256,128},HSL(Colors.UI_Hue,Colors.UI_Saturation,.65)},
alpha = 1,
},
['content-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_300,
alpha = .95,
position = {0,0,-1,0},
},
['content-topShadow'] = {
type = 'texture',
layer = 'ARTWORK',
gradient = {'VERTICAL','000000','000000'},
alpha = {.05,0},
position = {0,0,-1,nil},
height = 4,
},
['content-bottomShadow'] = {
type = 'texture',
layer = 'ARTWORK',
gradient = {'VERTICAL','000000','000000'},
alpha = {0,.05},
position = {0,0,nil,0},
height = 4,
},
['content-inline'] = {
type = 'outline',
layer = 'ARTWORK',
color = 'ffffff',
alpha = .02,
position = {0,0,-1,0},
},
['text-Font'] = {
type = 'font',
color = Colors.UI_F450,
},
}
local wireFrameSheet = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
alpha = 1,
},
['button-purple'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'aa00ff',
alpha = .5,
},
['content-yellow'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'fffc00',
alpha = .5,
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:SetStylesheet(Stylesheet)
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
self.button:SetHeight(self.settings.buttonHeight)
-- postion
self:ClearAllPoints()
if self.settings.position == 1 then
self:SetPoint('TOPLEFT')
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
-- set section name
self.text:SetText(self.settings.sectionName)
-- set section state
self[self.settings.expanded and 'Expand' or 'Collapse'](self)
-- set button visibility
self:SetButton(self.settings.button)
end,
['Collapse'] = function(self)
if not self.settings.button then self:UpdateHeight() return end
self.settings.expanded = false
self:FireEvent("OnStateChange", self.settings.position, 'Collapse')
self.textures['button-leftCollapseIcon']:SetAlpha(self.textures['button-leftCollapseIcon'].style.alpha[1])
self.textures['button-leftExpandIcon']:SetAlpha(0)
self.content:Hide()
self:UpdateHeight()
end,
['Expand'] = function(self)
self.settings.expanded = true
self:FireEvent("OnStateChange", self.settings.position, 'Expand')
self.textures['button-leftExpandIcon']:SetAlpha(self.textures['button-leftExpandIcon'].style.alpha[1])
self.textures['button-leftCollapseIcon']:SetAlpha(0)
self.content:Show()
self:UpdateHeight()
end,
['SetButton'] = function(self,state)
self.settings.button = state
self.button[state and 'Show' or 'Hide'](self.button)
if not state then
self:Expand()
else
self:UpdateHeight()
end
end,
['UpdateHeight'] = function(self)
local settings, children = self.settings, self.children
local contentHeight = 0
self.content:SetPoint('TOPLEFT',self.frame,0,settings.button and -settings.buttonHeight or 0)
if settings.expanded then
contentHeight = settings.contentPadding[3] + settings.contentPadding[4]
for i=1 , #children do contentHeight = contentHeight + children[i].frame:GetHeight() end
end
self.content:SetHeight(contentHeight)
self:SetHeight((settings.button and settings.buttonHeight or 0) + contentHeight)
self:FireEvent("OnHeightChange",contentHeight)
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
button = true,
contentPadding = {0,0,3,1 },
expanded = true,
buttonHeight = 16,
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local button = self:CreateRegion("Button", 'button', frame)
button:SetPoint('TOPRIGHT')
button:SetPoint('TOPLEFT')
button:SetScript("OnClick", function(this,button)
DiesalGUI:OnMouse(this,button)
self[self.settings.expanded and "Collapse" or "Expand"](self)
end)
local text = self:CreateRegion("FontString", 'text', button)
text:SetPoint("TOPLEFT",15,-2)
text:SetPoint("BOTTOMRIGHT",-15,0)
text:SetHeight(0)
text:SetJustifyH("MIDDLE")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local content = self:CreateRegion("Frame", 'content', frame)
content:SetPoint('TOPLEFT',frame,0,0)
content:SetPoint('TOPRIGHT',frame,0,0)
content:SetHeight(10)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,177 +0,0 @@
-- $Id: Bar.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- | Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Spinner |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "Bar"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .60,
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
position = 1,
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .60,
},
['bar-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_A100,ShadeColor(Colors.UI_A100,.1)},
position = 0,
},
['bar-inline'] = {
type = 'outline',
layer = 'BORDER',
gradient = {'VERTICAL','FFFFFF','FFFFFF'},
alpha = {.07,.02},
position = 0,
},
['bar-outline'] = {
type = 'texture',
layer = 'ARTWORK',
color = '000000',
alpha = .7,
width = 1,
position = {nil,1,0,0},
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['bar-green'] = {
type = 'outline',
layer = 'OVERLAY',
color = '55ff00',
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function round(num)
return floor((num + 1/2)/1) * 1
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:SetStylesheet(Stylesheet)
self:ApplySettings()
-- self:SetStylesheet(wireFrame)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
self:UpdateSize()
end,
['UpdateSize'] = function(self)
self:SetWidth(self.settings.width)
self:SetHeight(self.settings.height)
self.bar:SetPoint('TOPLEFT',self.settings.padding[1],-self.settings.padding[3])
self.bar:SetPoint('BOTTOMLEFT',self.settings.padding[1],self.settings.padding[4])
self.settings.barWidth = self.settings.width - self.settings.padding[1] - self.settings.padding[2]
self:UpdateBar()
end,
['SetColor'] = function(self, color, colorTop, gradientDirection)
end,
['SetSize'] = function(self, width, height)
width, height = tonumber(width), tonumber(height)
if not width then error('Bar:SetSize(width, height) width to be a number.',0) end
if not height then error('Bar:SetSize(width, height) height to be a number.',0) end
self.settings.width, self.settings.height = width, height
self:UpdateSize()
end,
['SetValue'] = function(self, number, min, max)
number, min, max = tonumber(number), tonumber(min), tonumber(max)
if not number then error('Bar:SetValue(number) number needs to be a number.',0) end
self.settings.min = min or self.settings.min
self.settings.max = max or self.settings.max
self.settings.value = number
self:UpdateBar()
end,
['SetMin'] = function(self, number)
number = tonumber(number)
if not number then error('Bar:SetMin(number) needs to be a number.',0) end
self.settings.min = number
self:UpdateBar()
end,
['SetMax'] = function(self, number)
number = tonumber(number)
if not number then error('Bar:SetMax(number) needs to be a number.',0) end
self.settings.max = number
self:UpdateBar()
end,
['UpdateBar'] = function(self)
local min, max, value, barWidth = self.settings.min, self.settings.max, self.settings.value, self.settings.barWidth
local width = round( (value - min) / (max - min) * barWidth )
if width == 0 then
self.bar:Hide()
else
self.bar:Show()
self.bar:SetWidth(width)
end
end,
['IsVisible'] = function(self)
return self.frame:IsVisible()
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 14, -- frame height (not bar)
width = 96, -- frame width (not bar)
padding = {1,1,1,1}, -- left, right, top, bottom (bar padding from frame)
value = 0,
min = 0,
max = 100,
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this)
self:FireEvent("OnHide")
end)
local bar = self:CreateRegion("Frame", 'bar', frame)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,279 +0,0 @@
-- $Id: Branch.lua 60 2016-11-04 01:34:23Z diesal2010 $
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub('DiesalStyle-1.0')
local DiesalGUI = LibStub('DiesalGUI-1.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 = 'Branch'
local Version = 1
-- ~~| Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['button-highlight'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .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 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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,
}
-- ~~| TableExplorerBranch Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,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" )
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)
button:SetScript( "OnDoubleClick", function(this,...)
self:FireEvent("OnDoubleClick",...)
end)
button:SetScript( "OnDragStart", function(this,...)
self:FireEvent("OnDragStart",...)
end)
button:SetScript( "OnDragStop", function(this,...)
self:FireEvent("OnDragStop",...)
end)
button:SetScript("OnEnter",function(this,...)
self:FireEvent("OnEnter",...)
end)
button:SetScript("OnLeave", function(this,...)
self:FireEvent("OnLeave",...)
end)
local icon = self:CreateRegion("Texture", 'icon', button)
DiesalStyle:StyleTexture(icon,{
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,109 +0,0 @@
-- $Id: Button.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
local GetSpellInfo, GetBonusBarOffset, GetDodgeChance = GetSpellInfo, GetBonusBarOffset, GetDodgeChance
local GetPrimaryTalentTree, GetCombatRatingBonus = GetPrimaryTalentTree, GetCombatRatingBonus
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local TYPE = "Button"
local VERSION = 5
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['text-color'] = {
type = 'Font',
color = 'b8c2cc',
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
["SetText"] = function(self, text)
self.text:SetText(text)
end,
["Disable"] = function(self)
self.settings.disabled = true
self.frame:Disable()
end,
["Enable"] = function(self)
self.settings.disabled = false
self.frame:Enable()
end,
["RegisterForClicks"] = function(self,...)
self.frame:RegisterForClicks(...)
end,
}
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor(name)
local self = DiesalGUI:CreateObjectBase(TYPE)
local frame = CreateFrame('Button',name,UIParent)
self.frame = frame
self.defaults = {
height = 32,
width = 32,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnClick, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local text = self:CreateRegion("FontString", 'text', frame)
text:SetPoint("TOPLEFT", 4, -1) -- sits below center when rendered off by 1 pixel, fuck you blizzard
text:SetPoint("BOTTOMRIGHT", -4, 0)
text:SetJustifyV("MIDDLE")
text:SetJustifyH("CENTER")
frame:SetFontString(text)
frame:SetScript("OnClick", function(this,button,...)
DiesalGUI:OnMouse(this,button)
self:FireEvent("OnClick",button,...)
end)
frame:SetScript("OnEnter", function(this)
self:FireEvent("OnEnter")
end)
frame:SetScript("OnLeave", function(this)
self:FireEvent("OnLeave")
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(TYPE,Constructor,VERSION)

@ -1,163 +0,0 @@
-- $Id: CheckBox.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
local GetSpellInfo, GetBonusBarOffset, GetDodgeChance = GetSpellInfo, GetBonusBarOffset, GetDodgeChance
local GetPrimaryTalentTree, GetCombatRatingBonus = GetPrimaryTalentTree, GetCombatRatingBonus
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local TYPE = "CheckBox"
local VERSION = 1
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .60,
position = -2
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .6,
position = -2
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
position = -1,
},
}
local checkBoxStyle = {
base = {
type = 'texture',
layer = 'ARTWORK',
color = Colors.UI_A400,
position = -3,
},
disabled = {
type = 'texture',
color = HSL(Colors.UI_Hue,Colors.UI_Saturation,.35),
},
enabled = {
type = 'texture',
color = Colors.UI_A400,
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
["SetChecked"] = function(self,value)
self.settings.checked = value
self.frame:SetChecked(value)
self[self.settings.disabled and "Disable" or "Enable"](self)
end,
["GetChecked"] = function(self)
return self.settings.checked
end,
["Disable"] = function(self)
self.settings.disabled = true
DiesalStyle:StyleTexture(self.check,checkBoxStyle.disabled)
self.frame:Disable()
end,
["Enable"] = function(self)
self.settings.disabled = false
DiesalStyle:StyleTexture(self.check,checkBoxStyle.enabled)
self.frame:Enable()
end,
["RegisterForClicks"] = function(self,...)
self.frame:RegisterForClicks(...)
end,
}
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(TYPE)
local frame = CreateFrame('CheckButton', nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 11,
width = 11,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnValueChanged, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local check = self:CreateRegion("Texture", 'check', frame)
DiesalStyle:StyleTexture(check,checkBoxStyle.base)
frame:SetCheckedTexture(check)
frame:SetScript('OnClick', function(this,button,...)
DiesalGUI:OnMouse(this,button)
if not self.settings.disabled then
self:SetChecked(not self.settings.checked)
if self.settings.checked then
-- PlaySound("igMainMenuOptionCheckBoxOn")
else
-- PlaySound("igMainMenuOptionCheckBoxOff")
end
self:FireEvent("OnValueChanged", self.settings.checked)
end
end)
frame:SetScript('OnEnter', function(this)
self:FireEvent("OnEnter")
end)
frame:SetScript('OnLeave', function(this)
self:FireEvent("OnLeave")
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(TYPE,Constructor,VERSION)

@ -1,282 +0,0 @@
-- $Id: ComboBox.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sub, format, lower, upper,gsub = string.sub, string.format, string.lower, string.upper, string.gsub
local tsort = table.sort
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBox |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'ComboBox'
local Version = 1
-- ~~| ComboBox Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .7,
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .7,
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
position = 1,
},
['button-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_500_GR[1],Colors.UI_500_GR[2]},
},
['button-outline'] = {
type = 'outline',
layer = 'ARTWORK',
color = '000000',
alpha = .9,
},
['button-inline'] = {
type = 'outline',
layer = 'BORDER',
gradient = {'VERTICAL','FFFFFF','FFFFFF'},
alpha = {.07,.02},
position = -1,
},
['button-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .05,
},
['button-arrow'] = {
type = 'texture',
layer = 'BORDER',
image = {'DiesalGUIcons',{2,1,16,256,128}},
alpha = .5,
position = {nil,-4,-5,nil},
height = 4,
width = 5,
},
['editBox-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .1,
position = {-1,0,-1,-1},
},
['editBox-font'] = {
type = 'Font',
color = Colors.UI_TEXT,
},
['dropdown-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_100,
alpha = .95,
},
['dropdown-inline'] = {
type = 'outline',
layer = 'BORDER',
color = 'ffffff',
alpha = .02,
position = -1,
},
['dropdown-shadow'] = {
type = 'shadow',
},
}
-- ~~| ComboBox Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a,b)
return a.value < b.value
end
local function sortList(list,orderedKeys)
if orderedKeys then return orderedKeys end
local sortedList = {}
local orderedKeys = {}
for key,value in pairs(list) do
sortedList[#sortedList + 1] = {key=key,value=value}
end
tsort(sortedList,compare)
for i,value in ipairs(sortedList) do
orderedKeys[#orderedKeys + 1] = value.key
end
return orderedKeys
end
-- ~~| ComboBox Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
local settings = self.settings
local content = self.content
local frame = self.frame
local children = self.children
local dropdown = self.dropdown
frame:SetWidth(settings.width)
frame:SetHeight(settings.height)
self.editBox:SetPoint('RIGHT',-settings.buttonWidth,0)
self.button:SetWidth(settings.buttonWidth)
-- dropdown
content:SetPoint("TOPLEFT",settings.dropdownPadding[1],-settings.dropdownPadding[3])
content:SetPoint("BOTTOMRIGHT",-settings.dropdownPadding[2],settings.dropdownPadding[4])
local menuHeight = 0
for i=1 , #children do
menuHeight = menuHeight + children[i].frame:GetHeight()
end
dropdown:SetHeight(settings.dropdownPadding[3] + menuHeight + settings.dropdownPadding[4])
end,
['SetList'] = function(self,list,orderedKeys)
self:ReleaseChildren()
self:SetText('')
local settings = self.settings
local orderedKeys = sortList(list,orderedKeys)
settings.list = list
for position, key in ipairs(orderedKeys) do
local comboBoxItem = DiesalGUI:Create('ComboBoxItem')
self:AddChild(comboBoxItem)
comboBoxItem:SetParentObject(self)
comboBoxItem:SetSettings({
key = key,
value = list[key],
position = position,
},true)
end
self:ApplySettings()
end,
['SetValue'] = function(self,key)
for i=1,#self.children do
self.children[i]:SetSelected(false)
end
for i=1,#self.children do
if self.children[i].settings.key == key then
self.children[i]:SetSelected(true)
self:SetText(self.children[i].settings.value)
self.editBox:SetCursorPosition(0)
break end
end
end,
['SetText'] = function(self,text)
self.editBox:SetText(text)
end,
['SetJustify'] = function(self,j)
self.editBox:SetJustifyH(j)
end,
['SetFocus'] = function(self)
DiesalGUI:SetFocus(self)
end,
['ClearFocus'] = function(self)
self.dropdown:Hide()
end,
['ClearSelection'] = function(self)
for i=1,#self.children do
self.children[i]:SetSelected(false)
end
self:SetText('')
end,
}
-- ~~| ComboBox Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
width = 100,
height = 16,
buttonWidth = 16,
dropdownPadding = {4,4,4,4},
dropdownButtonWidth = 16,
}
-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnValueSelected, OnRenameValue
-- OnEnter, OnLeave
-- OnButtonClick, OnButtonEnter, OnButtonLeave
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local editBox = self:CreateRegion("EditBox", 'editBox', frame)
editBox:SetPoint("TOPLEFT")
editBox:SetPoint("BOTTOMLEFT")
editBox:SetAutoFocus(false)
editBox:SetJustifyH("RIGHT")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(1,2,2,0)
editBox:SetScript('OnEnterPressed', function(this)
local text = this:GetText()
DiesalGUI:ClearFocus()
if text ~= self.settings.oldValue then self:FireEvent("OnRenameValue",self.settings.selectedKey,text) end
end)
editBox:HookScript('OnEscapePressed', function(this,...)
this:SetText(self.settings.oldValue)
end)
editBox:HookScript('OnEditFocusGained', function(this)
self.settings.oldValue = this:GetText()
end)
editBox:HookScript('OnEditFocusLost', function(this,...)
self:SetText(self.settings.oldValue)
end)
editBox:SetScript("OnEnter",function(this)
self:FireEvent("OnEnter")
end)
editBox:SetScript("OnLeave", function(this)
self:FireEvent("OnLeave")
end)
local button = self:CreateRegion("Button", 'button', frame)
button:SetPoint('TOPRIGHT')
button:SetPoint('BOTTOMRIGHT')
button:SetScript("OnEnter",function(this)
self:FireEvent("OnButtonEnter")
end)
button:SetScript("OnLeave", function(this)
self:FireEvent("OnButtonLeave")
end)
button:SetScript("OnClick", function(this, button)
self:FireEvent("OnButtonClick")
local dropdown = self.dropdown
local visible = dropdown:IsVisible()
DiesalGUI:OnMouse(this,button)
dropdown[visible and "Hide" or 'Show'](dropdown)
end)
local dropdown = self:CreateRegion("Frame", 'dropdown', frame)
dropdown:SetFrameStrata("FULLSCREEN_DIALOG")
dropdown:SetPoint('TOPRIGHT',frame,'BOTTOMRIGHT',0,-2)
dropdown:SetPoint('TOPLEFT',frame,'BOTTOMLEFT',0,-2)
dropdown:SetScript("OnShow", function(this) self:SetFocus() end)
dropdown:Hide()
self:CreateRegion("Frame", 'content', dropdown)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,122 +0,0 @@
-- $Id: ComboBoxItem.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBoxItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'ComboBoxItem'
local Version = 2
-- ~~| ComboBoxItem Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'b3d9ff',
alpha = .05,
},
}
-- ~~| ComboBoxItem Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBoxItem Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self)
self.check:Hide()
end,
['ApplySettings'] = function(self)
if not self.settings.key then return end
local settings = self.settings
local comboBoxSettings = settings.parentObject.settings
local text = self.text
if settings.position == 1 then
self:SetPoint('TOPLEFT')
self:SetPoint('RIGHT')
else
self:SetPoint('TOPLEFT',settings.parentObject.children[settings.position-1].frame,'BOTTOMLEFT',0,0)
self:SetPoint('RIGHT')
end
self:SetHeight(comboBoxSettings.dropdownButtonWidth)
self:SetText(settings.value)
end,
['SetText'] = function(self,text)
self.text:SetText(text)
end,
['OnClick'] = function(self)
local settings = self.settings
local comboBox = settings.parentObject
local comboBoxSettings = comboBox.settings
local comboBoxItems = comboBox.children
for i=1,#comboBoxItems do
comboBoxItems[i]:SetSelected(false)
end
self:SetSelected(true)
comboBox.dropdown:Hide()
comboBox:SetText(settings.value)
comboBox:FireEvent("OnValueSelected",settings.key,settings.value)
end,
['SetSelected'] = function(self,selected)
if selected then
self.settings.parentObject.settings.selectedKey = self.settings.key
self.settings.selected = true
self.check:Show()
else
self.settings.selected = false
self.check:Hide()
end
end,
}
-- ~~| ComboBoxItem Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Button',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = { }
-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnClick", function(this,button) self:OnClick() end)
frame:SetScript('OnEnter', function(this) end)
frame:SetScript('OnLeave', function(this) end)
local text = self:CreateRegion("FontString", 'text', frame)
text:SetPoint("TOPLEFT",12,-2)
text:SetPoint("BOTTOMRIGHT",0,0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", 'check', frame)
DiesalStyle:StyleTexture(check,{
position = {2,nil,0,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons', {10,5,16,256,128},'FFFF00'},
})
check:Hide()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,296 +0,0 @@
-- $Id: DropDown.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local tsort = table.sort
local sub, format, lower, upper,gsub = string.sub, string.format, string.lower, string.upper, string.gsub
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Dropdown |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'Dropdown'
local Version = 2
-- ~~| Dropdown Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_400_GR[1],Colors.UI_400_GR[2]},
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
gradient = {'VERTICAL','FFFFFF','FFFFFF'},
alpha = {.07,.02},
position = -1,
},
['frame-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .05,
},
['frame-arrow'] = {
type = 'texture',
layer = 'BORDER',
image = {'DiesalGUIcons',{2,1,16,256,128}},
alpha = .5,
position = {nil,-5,-7,nil},
height = 3,
width = 5,
},
['text-color'] = {
type = 'Font',
color = Colors.UI_TEXT,
},
['dropdown-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_100,
alpha = .95,
},
['dropdown-inline'] = {
type = 'outline',
layer = 'BORDER',
color = 'ffffff',
alpha = .02,
position = -1,
},
['dropdown-shadow'] = {
type = 'shadow',
},
}
-- ~~| Dropdown Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a,b)
return a.value < b.value
end
local function sortList(list,orderedKeys)
if orderedKeys then return orderedKeys end
local sortedList = {}
local orderedKeys = {}
for key,value in pairs(list) do
sortedList[#sortedList + 1] = {key=key,value=value}
end
tsort(sortedList,compare)
for i,value in ipairs(sortedList) do
orderedKeys[#orderedKeys + 1] = value.key
end
return orderedKeys
end
-- ~~| Dropdown Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
local settings = self.settings
local content = self.content
local frame = self.frame
local children = self.children
local dropdown = self.dropdown
frame:SetWidth(settings.width)
frame:SetHeight(settings.height)
content:SetPoint("TOPLEFT",settings.dropdownPadLeft,-settings.dropdownPadTop)
content:SetPoint("BOTTOMRIGHT",-settings.dropdownPadRight,settings.dropdownPadBottom)
local menuHeight = 0
for i=1 , #children do
menuHeight = menuHeight + children[i].frame:GetHeight()
end
dropdown:SetHeight(settings.dropdownPadTop + menuHeight + settings.dropdownPadBottom)
end,
['SetList'] = function(self,list,orderedKeys)
self:ReleaseChildren()
self:SetText('')
local settings = self.settings
local orderedKeys = sortList(list,orderedKeys)
settings.list = list
for position, key in ipairs(orderedKeys) do
local dropdownItem = DiesalGUI:Create('DropdownItem')
self:AddChild(dropdownItem)
dropdownItem:SetParentObject(self)
dropdownItem:SetSettings({
key = key,
value = list[key],
position = position,
},true)
end
self:ApplySettings()
end,
['SetValue'] = function(self,key)
local selectionTable = {}
local selectedKey, dropdownText, selectedValue
if key ~='CLEAR' then
if self.settings.multiSelect then
for i=1,#self.children do
if self.children[i].settings.key == key then selectedKey = key; self.children[i]:SetSelected(true) end
if self.children[i].settings.selected then
if dropdownText then
dropdownText = format('%s, %s',dropdownText,self.children[i].settings.value)
else
dropdownText = self.children[i].settings.value
end
selectionTable[#selectionTable+1] = self.children[i].settings.key
end
end
else
for i=1,#self.children do
self.children[i]:SetSelected(false)
if self.children[i].settings.key == key then
self.children[i]:SetSelected(true)
dropdownText = self.children[i].settings.value
selectionTable = {key}
selectedKey = key
selectedValue = value
end
end
end
else
self:ClearSelection()
end
if selectedKey then
self:SetText(dropdownText)
self:FireEvent("OnValueChanged",selectedKey,selectedValue,selectionTable)
else
self:SetText('')
self:FireEvent("OnValueChanged",selectedKey,selectedValue,selectionTable)
end
end,
['ClearSelection'] = function(self)
for i=1,#self.children do
self.children[i]:SetSelected(false)
end
self:SetText('')
end,
['SetValueTable'] = function(self,keyTable)
if not self.settings.multiSelect or type(keyTable) ~='table' then return end
local dropdownItems = self.children
local selectionTable = {}
local selectedKey
local dropdownText
for i=1,#dropdownItems do
local dropdownItem = dropdownItems[i]
dropdownItem:SetSelected(false)
for _,key in ipairs(keyTable) do
if dropdownItem.settings.key == key then
dropdownItem:SetSelected(true)
if dropdownText then
dropdownText = format('%s, %s',dropdownText,dropdownItem.settings.value)
else
dropdownText = dropdownItem.settings.value
end
selectionTable[#selectionTable+1] = dropdownItem.settings.key
end
end
end
self:FireEvent("OnValueChanged",nil,nil,selectionTable)
self:SetText(dropdownText)
end,
['SetMultiSelect'] = function(self,state)
self.settings.multiSelect = state
end,
['SetText'] = function(self,text)
self.text:SetText(text)
end,
['SetFocus'] = function(self)
DiesalGUI:SetFocus(self)
end,
['ClearFocus'] = function(self)
self.dropdown:Hide()
end,
['EnableMouse'] = function(self,state)
self.frame:EnableMouse(state)
end,
["RegisterForClicks"] = function(self,...)
self.frame:RegisterForClicks(...)
end,
['SetJustifyV'] = function(self,justify)
self.text:SetJustifyV(justify)
end,
['SetJustifyH'] = function(self,justify)
self.text:SetJustifyH(justify)
end,
}
-- ~~| Dropdown Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Button',nil,UIParent)
self.frame = frame
self.defaults = {
dropdownPadLeft = 4,
dropdownPadRight = 4,
dropdownPadTop = 4,
dropdownPadBottom = 4,
itemHeight = 16,
width = 100,
height = 16,
}
-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnValueChanged(event,selectedKey,selectedValue,selectionTable)
-- OnValueSelected(event,selectedKey,selectedValue,selectionTable)
-- OnEnter, OnLeave
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnMouseUp", function(this, button)
if button == 'LeftButton' then
local dropdown = self.dropdown
local visible = dropdown:IsVisible()
DiesalGUI:OnMouse(this,button)
dropdown[visible and "Hide" or 'Show'](dropdown)
end
end)
frame:SetScript("OnClick", function(this, ...)
self:FireEvent("OnClick", ...)
end)
frame:SetScript("OnEnter",function(this,...)
self:FireEvent("OnEnter",...)
end)
frame:SetScript("OnLeave", function(this,...)
self:FireEvent("OnLeave",...)
end)
local text = self:CreateRegion("FontString", 'text', frame)
text:ClearAllPoints()
text:SetPoint("TOPLEFT", 4, -1)
text:SetPoint("BOTTOMRIGHT", -14, 1)
text:SetJustifyV("MIDDLE")
text:SetJustifyH("LEFT")
local dropdown = self:CreateRegion("Frame", 'dropdown', frame)
dropdown:SetFrameStrata("FULLSCREEN_DIALOG")
dropdown:SetPoint('TOPRIGHT',frame,'BOTTOMRIGHT',0,-2)
dropdown:SetPoint('TOPLEFT',frame,'BOTTOMLEFT',0,-2)
dropdown:SetScript("OnShow", function(this) self:SetFocus() end)
dropdown:Hide()
self:CreateRegion("Frame", 'content', dropdown)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,137 +0,0 @@
-- $Id: DropDownItem.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sub, format, lower, upper,gsub = string.sub, string.format, string.lower, string.upper, string.gsub
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| DropdownItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'DropdownItem'
local Version = 2
-- ~~| DropdownItem Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'b3d9ff',
alpha = .1,
},
}
-- ~~| DropdownItem Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
['OnRelease'] = function(self)
self.check:Hide()
end,
['ApplySettings'] = function(self)
if not self.settings.key then return end
local settings = self.settings
local dropdownSettings = settings.parentObject.settings
local text = self.text
if settings.position == 1 then
self:SetPoint('TOPLEFT')
self:SetPoint('RIGHT')
else
self:SetPoint('TOPLEFT',settings.parentObject.children[settings.position-1].frame,'BOTTOMLEFT',0,0)
self:SetPoint('RIGHT')
end
self:SetHeight(dropdownSettings.itemHeight)
self:SetText(settings.value)
end,
['SetText'] = function(self,text)
self.text:SetText(text)
end,
['OnClick'] = function(self)
local settings = self.settings
local dropdown = settings.parentObject
local dropdownSettings= dropdown.settings
local dropdownItems = dropdown.children
local selectionTable = {}
local dropdownText
if settings.key ~= 'CLEAR' then
if dropdownSettings.multiSelect then
self:SetSelected(not settings.selected)
for i=1,#dropdownItems do
if dropdownItems[i].settings.selected then
if dropdownText then
dropdownText = format('%s, %s',dropdownText,dropdownItems[i].settings.value)
else
dropdownText = dropdownItems[i].settings.value
end
selectionTable[#selectionTable+1] = dropdownItems[i].settings.key
end
end
else
for i=1,#dropdownItems do
dropdownItems[i]:SetSelected(false)
end
self:SetSelected(true)
dropdownText = settings.value
selectionTable = {settings.key}
dropdown.dropdown:Hide()
end
else
dropdown.dropdown:Hide()
dropdown:ClearSelection()
end
dropdown:SetText(dropdownText)
dropdown:FireEvent("OnValueChanged",settings.key,settings.value,selectionTable)
dropdown:FireEvent("OnValueSelected",settings.key,settings.value,selectionTable)
end,
['SetSelected'] = function(self,selected)
if selected then
self.settings.selected = true
self.check:Show()
else
self.settings.selected = false
self.check:Hide()
end
end,
}
-- ~~| DropdownItem Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Button',nil,UIParent)
self.frame = frame
self.defaults = { }
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnClick", function(this,button) self:OnClick() end)
frame:SetScript('OnEnter', function(this) end)
frame:SetScript('OnLeave', function(this) end)
local text = self:CreateRegion("FontString", 'text', frame)
text:SetPoint("TOPLEFT",12,-2)
text:SetPoint("BOTTOMRIGHT",0,0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", 'check', frame)
DiesalStyle:StyleTexture(check,{
position = {2,nil,0,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons', {10,5,16,256,128},'FFFF00'},
})
check:Hide()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,124 +0,0 @@
-- $Id: Input.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Input |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "Input"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .6,
},
['editBox-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
position = 1,
},
['editBox-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .7,
},
['editBox-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = 'ffffff',
alpha = .05,
position = -1,
},
['editBox-font'] = {
type = 'Font',
color = Colors.UI_TEXT,
},
}
-- ~~| Spinner Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:SetStylesheet(Stylesheet)
self:ApplySettings()
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
self:SetWidth( self.settings.width)
self:SetHeight( self.settings.height)
end,
['GetText'] = function(self)
return self.editBox:GetText()
end,
['SetText'] = function(self,txt)
self.editBox:SetText(txt)
end,
['SetTextColor'] = function(self,color,alpha)
alpha = alpha or 1
color = {DiesalTools.GetColor(color)}
self.editBox:SetTextColor(color[1],color[2],color[3],alpha)
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
self.defaults = {
height = 16,
width = 50,
mouse = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnEnter, OnLeave, OnEnterPressed, OnValueChanged
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this)
self:FireEvent("OnHide")
end)
local editBox = self:CreateRegion("EditBox", 'editBox', frame)
editBox:SetAllPoints()
editBox:SetAutoFocus(false)
editBox:SetJustifyH("LEFT")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(3,0,2,0)
editBox:SetScript('OnEnterPressed', function(this,...)
self:FireEvent("OnEnterPressed",...)
DiesalGUI:ClearFocus()
end)
editBox:HookScript('OnEscapePressed', function(this,...)
self:FireEvent("OnEscapePressed",...)
end)
editBox:HookScript('OnEditFocusLost', function(this,...)
self:FireEvent("OnEditFocusLost",...)
end)
editBox:HookScript('OnEditFocusGained', function(this,...)
self:FireEvent("OnEditFocusGained",...)
end)
editBox:SetScript("OnEnter",function(this,...)
self:FireEvent("OnEnter",...)
end)
editBox:SetScript("OnLeave", function(this,...)
self:FireEvent("OnLeave",...)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,163 +0,0 @@
-- $Id: QuickDoc.lua 60 2016-11-04 01:34:23Z diesal2010 $
-- | Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
local DiesalGUI = LibStub("DiesalGUI-1.0")
local DiesalMenu = LibStub('DiesalMenu-1.0')
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local print, type, select, tostring, tonumber = print, type, select, tostring, tonumber
local sub, format, match, lower = string.sub, string.format, string.match, string.lower
local table_sort = table.sort
local abs = math.abs
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | TableExplorer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local QuickDoc
local Type = "QuickDoc"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local windowStylesheet = {
['content-background'] = {
type = 'texture',
color = '131517',
},
}
-- | Local |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local doc = {
{ type = 'section',
margin = {0,0,0,0},
padding = {0,0,0,0},
style = {},
{ type = 'single-line', text = 'Editor',
font = nil.
fontSize = 14,
text = 'Editor',
},
{ type = 'columns', text = 'Editor',
font = nil.
fontSize = 14,
text = 'Editor',
},
}
}
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self.settings = DiesalTools.TableCopy( self.defaults )
self:ApplySettings()
self:Show()
end,
['OnRelease'] = function(self)
self.tree:ReleaseChildren()
end,
['ApplySettings'] = function(self)
end,
['BuildDoc'] = function(self,doc)
if #doc == 0 then error('BuildDoc(doc) doc requires atleast one section')
local settings = self.settings
-- reset
self:ReleaseChildren()
-- setup
settings.doc = doc
if #doc == 0 then
tree:UpdateHeight()
self.statusText:SetText('|cffff0000Table is empty.')
return end
-- sort tree table
local sortedTable = sortTable(settings.exploredTable)
-- build Tree Branches
for position, key in ipairs(sortedTable) do
if self.settings.endtime <= time() then self:Timeout() return end
self:BuildBranch(self.tree,key[2],settings.exploredTable[key[2]],position,1,position == #sortedTable)
end
end,
['BuildSection'] = function(self,parent,key,value,position,depth,last)
local tree = self.tree
local leaf = type(value) ~= 'table' or next(value) == nil or depth >= self.settings.maxDepth
local branch = DiesalGUI:Create('Branch')
-- | Reset Branch |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
branch:ReleaseChildren()
-- | setup Branch |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
branch:SetParentObject(parent)
parent:AddChild(branch)
branch:SetSettings({
key = key,
value = value,
position = position,
depth = depth,
last = last,
leaf = leaf,
})
branch:SetEventListener('OnClick',function(this,event,button)
if button =='RightButton' then
if not next(this.settings.menuData) then return end
DiesalMenu:Menu(this.settings.menuData,this.frame,10,-10)
end
end)
self:SetBranchLabel(branch,key,value,leaf)
self:SetBranchMenu(branch,key,value)
self:SetBranchIcon(branch,type(value))
if value == tree or leaf then branch:ApplySettings() return end
-- | sort Branch Table |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sortedTable = sortTable(value)
-- | build Branch Branches |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for position, key in ipairs(sortedTable) do
if self.settings.endtime <= time() then self:Timeout() return end
self:BuildBranch(branch,key[2],value[key[2]],position,depth+1,position == #sortedTable)
end
-- | Update Branch | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
branch:ApplySettings()
end,
['Show'] = function(self)
self.window:Show()
end,
}
-- ~~| TableExplorer Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
QuickDoc = DiesalGUI:CreateObjectBase(Type)
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
QuickDoc.defaults = {
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local window = DiesalGUI:Create('Window')
window:SetSettings({
header = false,
footer = false,
top = UIParent:GetHeight() - 100,
left = 100,
height = 300,
width = 400,
minWidth = 200,
minHeight = 200,
},true)
window:SetStylesheet(windowStylesheet)
-- ~~ Frames ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
QuickDoc.window = window
QuickDoc.content = window.content
QuickDoc.frame = window.frame
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do QuickDoc[method] = func end
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return QuickDoc
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,279 +0,0 @@
-- $Id: ScrollFrame.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollFrame |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'ScrollFrame'
local Version = 3
-- ~~| ScrollFrame Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['track-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .3,
},
['grip-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_400,
},
['grip-inline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['scrollFrameContainer-yellow'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffff00',
},
['scrollFrame-orange'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ff7f00',
},
['scrollBar-blue'] = {
type = 'outline',
layer = 'OVERLAY',
color = '0080ff',
},
['track-green'] = {
type = 'outline',
layer = 'OVERLAY',
color = '00ff00',
},
['grip-purple'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'a800ff',
},
}
-- ~~| ScrollFrame Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local internal
-- ~~| ScrollFrame Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
--self:SetStylesheet(wireFrame)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
local settings = self.settings
local scrollFrame = self.scrollFrame
scrollFrame:SetPoint('TOPLEFT',settings.contentPadding[1],-settings.contentPadding[3])
scrollFrame:SetPoint('BOTTOMRIGHT',-settings.contentPadding[2],settings.contentPadding[4])
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.scrollBar:SetPoint('TOPRIGHT',-settings.scrollBarPadding[2],-settings.scrollBarPadding[3])
self.scrollBar:SetPoint('BOTTOMRIGHT',-settings.scrollBarPadding[2],settings.scrollBarPadding[4])
if settings.scrollBarButtons then
self.track:SetPoint('TOP',0,-settings.scrollBarButtonHeight)
self.track:SetPoint('BOTTOM',0,settings.scrollBarButtonHeight)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:Show()
self.buttonDown:Show()
else
self.track:SetPoint('TOP',0,0)
self.track:SetPoint('BOTTOM',0,0)
self.buttonUp:Hide()
self.buttonDown:Hide()
end
self.content:SetHeight(settings.contentHeight)
end,
['SetContentHeight'] = function(self,height)
height = height < 1 and 1 or height -- height of 0 wont hide scrollbar
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
['SetGripSize'] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
['SetScrollThumbPosition'] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then self.grip:SetPoint('TOP',0,0) return end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint('TOP',0,-gripPositionOnTrack)
end,
['ShowScrollBar'] = function(self,show)
if show then
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',-(self.settings.scrollBarWidth + self.settings.scrollBarPadding[1] + self.settings.scrollBarPadding[2]),0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',0,0)
end
end,
['ScrollToBottom'] = function(self)
local scrollRange = self.scrollFrame:GetVerticalScrollRange()
if scrollRange > 0 and scrollRange ~= self.scrollFrame:GetVerticalScroll() then
self.scrollFrame:SetVerticalScroll(scrollRange)
end
end,
['SetVerticalScroll'] = function(self,num)
self.scrollFrame:SetVerticalScroll(num)
end,
['GetVerticalScroll'] = function(self)
return self.scrollFrame:GetVerticalScroll()
end,
['GetVerticalScrollRange'] = function(self)
return self.scrollFrame:GetVerticalScrollRange()
end,
['VerticallyScroll'] = function(self,num)
if num < 0 then
self.scrollFrame:SetVerticalScroll(max( self.scrollFrame:GetVerticalScroll() + num, 0))
else
self.scrollFrame:SetVerticalScroll(min( self.scrollFrame:GetVerticalScroll() + num, self.scrollFrame:GetVerticalScrollRange()))
end
end,
}
-- ~~| ScrollFrame Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 300,
width = 500,
scrollBarButtonHeight = 4,
scrollBarWidth = 4,
scrollBarButtons = false,
scrollBarPadding = {0,0,0,0},
contentPadding = {0,0,0,0},
contentHeight = 1,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this)
self:FireEvent("OnHide")
end)
local scrollFrameContainer = self:CreateRegion("Frame", 'scrollFrameContainer', frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", 'scrollFrame', scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this,delta)
DiesalGUI:OnMouse(this,'MouseWheel')
if delta > 0 then
self:VerticallyScroll(-25)
else
self:VerticallyScroll(25)
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this,offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this,horizontalScrollRange, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return end
this:SetVerticalScroll(min(this:GetVerticalScroll(),verticalScrollRange))
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this,width,height)
self.content:SetWidth(width)
end)
scrollFrame:SetScrollChild(self:CreateRegion("Frame", 'content', scrollFrame))
scrollFrame:RegisterForDrag("LeftButton")
scrollFrame:SetScript( "OnDragStart", function(this,...)
self:FireEvent("OnDragStart",...)
end)
local scrollBar = self:CreateRegion("Frame", 'scrollBar', frame)
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", 'buttonUp', scrollBar)
buttonUp:SetPoint('TOPLEFT')
buttonUp:SetPoint('TOPRIGHT')
local buttonDown = self:CreateRegion("Frame", 'buttonDown', scrollBar)
buttonDown:SetPoint('BOTTOMLEFT')
buttonDown:SetPoint('BOTTOMRIGHT')
local track = self:CreateRegion("Frame", 'track', scrollBar)
track:SetPoint('LEFT')
track:SetPoint('RIGHT')
local grip = self:CreateRegion("Frame", 'grip', track)
grip:SetPoint('LEFT')
grip:SetPoint('RIGHT')
grip:SetPoint('TOP')
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this,button)
DiesalGUI:OnMouse(this,button)
if button ~= 'LeftButton' then return end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5,this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale ))
newGripPosition = min(max(newGripPosition,0),trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
scrollFrame:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this,button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,279 +0,0 @@
-- $Id: ScrollingEditBox.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollingEditBox |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'ScrollingEditBox'
local Version = 3
-- ~~| ScrollingEditBox Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['track-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .3,
},
['grip-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_400,
},
['grip-inline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['scrollFrameContainer-yellow'] = {
type = 'outline',
layer = 'BACKGROUND',
color = 'fffc00',
},
['scrollFrame-orange'] = {
type = 'outline',
layer = 'BORDER',
color = 'ffd400',
},
['editBox-red'] = {
type = 'outline',
layer = 'ARTWORK',
color = 'ff0000',
aplha = .5,
},
['scrollBar-blue'] = {
type = 'outline',
layer = 'OVERLAY',
color = '00aaff',
},
['track-green'] = {
type = 'outline',
layer = 'OVERLAY',
color = '55ff00',
},
}
-- ~~| ScrollingEditBox Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ScrollingEditBox Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
local settings = self.settings
self.scrollFrame:SetPoint('TOPLEFT',settings.contentPadding[1],-settings.contentPadding[3])
self.scrollFrame:SetPoint('BOTTOMRIGHT',-settings.contentPadding[2],settings.contentPadding[4])
self.scrollBar:SetPoint('TOPRIGHT',0,-settings.contentPadding[3] + 1)
self.scrollBar:SetPoint('BOTTOMRIGHT',0,settings.contentPadding[4] - 1)
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
self.editBox:SetJustifyH(settings.justifyH)
self.editBox:SetJustifyV(settings.justifyV)
end,
['ShowScrollBar'] = function(self,show)
if show then
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',-(self.settings.scrollBarWidth + 1),0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',0,0)
end
end,
['SetContentHeight'] = function(self,height)
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
['SetGripSize'] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
['SetScrollThumbPosition'] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then self.grip:SetPoint('TOP',0,0) return end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint('TOP',0,-gripPositionOnTrack)
end,
['SetVerticalScroll'] = function(self,scroll) -- user scrolled only
self.settings.forceScrollBottom = DiesalTools.Round(scroll) == DiesalTools.Round(self.scrollFrame:GetVerticalScrollRange())
self.scrollFrame:SetVerticalScroll(scroll)
end,
['SetText'] = function(self,txt)
self.settings.text = txt
self.editBox:SetText(txt or '')
end,
}
-- ~~| ScrollingEditBox Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
scrollBarButtonHeight = 1,
scrollBarWidth = 4,
contentPadding = {0,0,0,0},
justifyH = "LEFT",
justifyV = "TOP",
forceScrollBottom = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this) self:FireEvent("OnHide") end)
local scrollFrameContainer = self:CreateRegion("Frame", 'scrollFrameContainer', frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", 'scrollFrame', scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this,delta)
DiesalGUI:OnMouse(this,'MouseWheel')
if delta > 0 then
self:SetVerticalScroll(max( this:GetVerticalScroll() - 50, 0))
else
self:SetVerticalScroll(min( this:GetVerticalScroll() + 50, this:GetVerticalScrollRange()))
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this,offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this,xOffset, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return end
if self.settings.forceScrollBottom then
this:SetVerticalScroll(verticalScrollRange)
else
this:SetVerticalScroll(min(this:GetVerticalScroll(),verticalScrollRange))
end
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this,width,height)
self.editBox:SetWidth(width)
end)
local editBox = self:CreateRegion("EditBox", 'editBox', scrollFrame)
editBox:SetPoint("TOPLEFT")
editBox:SetPoint("TOPRIGHT")
editBox:SetAutoFocus(false)
editBox:SetMultiLine(true)
editBox:HookScript('OnEditFocusLost',function(this)
this:HighlightText(0,0)
-- this:SetText(self.settings.text)
end)
editBox:HookScript('OnEditFocusGained',function(this)
self:FireEvent("OnEditFocusGained")
end)
editBox:HookScript('OnEscapePressed',function(this)
self:FireEvent("OnEscapePressed")
end)
editBox:HookScript('OnTabPressed',function(this)
self:FireEvent("OnTabPressed")
end)
editBox:HookScript('OnCursorChanged',function(this,...)
self:FireEvent("OnCursorChanged",...)
end)
editBox:HookScript('OnTextChanged',function(this)
self:FireEvent("OnTextChanged")
end)
scrollFrame:SetScrollChild(editBox)
local scrollBar = self:CreateRegion("Frame", 'scrollBar', frame)
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", 'buttonUp', scrollBar)
buttonUp:SetPoint('TOPLEFT')
buttonUp:SetPoint('TOPRIGHT')
local buttonDown = self:CreateRegion("Frame", 'buttonDown', scrollBar)
buttonDown:SetPoint('BOTTOMLEFT')
buttonDown:SetPoint('BOTTOMRIGHT')
local track = self:CreateRegion("Frame", 'track', scrollBar)
track:SetPoint('LEFT')
track:SetPoint('RIGHT')
track:SetPoint('TOP',buttonUp,'BOTTOM',0,0)
track:SetPoint('BOTTOM',buttonDown,'TOP',0,0)
local grip = self:CreateRegion("Frame", 'grip', track)
grip:SetPoint('LEFT')
grip:SetPoint('RIGHT')
grip:SetPoint('TOP')
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this,button)
DiesalGUI:OnMouse(this,button)
if button ~= 'LeftButton' then return end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5,this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale ))
newGripPosition = min(max(newGripPosition,0),trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
self:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this,button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,267 +0,0 @@
-- $Id: ScrollingMessageFrame.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub('DiesalGUI-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollingMessageFrame |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'ScrollingMessageFrame'
local Version = 1
-- ~~| ScrollingMessageFrame Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['track-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '0e0e0e',
},
['track-outline'] = {
type = 'outline',
layer = 'BORDER',
color = '060606',
},
['grip-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = 'HORIZONTAL',
color = '5d5d5d',
colorEnd = '252525',
},
['grip-outline'] = {
type = 'outline',
layer = 'BORDER',
color = '060606',
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['scrollFrameContainer-yellow'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'fffc00',
},
['scrollFrame-orange'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffd400',
},
['scrollingMessageFrame-red'] = {
type = 'outline',
layer = 'BORDER',
color = 'ff0000',
aplha = .5,
},
['scrollBar-blue'] = {
type = 'outline',
layer = 'OVERLAY',
color = '00aaff',
},
['track-green'] = {
type = 'outline',
layer = 'OVERLAY',
color = '55ff00',
},
}
-- ~~| ScrollingMessageFrame Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ScrollingMessageFrame Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:SetStylesheet(wireFrame)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
local settings = self.settings
local scrollFrame = self.scrollFrame
scrollFrame:SetPoint('TOPLEFT',settings.contentPadLeft,-settings.contentPadTop)
scrollFrame:SetPoint('BOTTOMRIGHT',-settings.contentPadRight,settings.contentPadBottom)
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
end,
['ShowScrollBar'] = function(self,show)
if show then
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',-(self.settings.scrollBarWidth + 1),0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint('BOTTOMRIGHT',0,0)
end
end,
['SetContentHeight'] = function(self,height)
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
['SetGripSize'] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
['SetScrollThumbPosition'] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then self.grip:SetPoint('TOP',0,0) return end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint('TOP',0,-gripPositionOnTrack)
end,
['SetVerticalScroll'] = function(self,scroll) -- user scrolled only
self.settings.forceScrollBottom = DiesalTools.Round(scroll) == DiesalTools.Round(self.scrollFrame:GetVerticalScrollRange())
self.scrollFrame:SetVerticalScroll(scroll)
end,
['AddMessage'] = function(self,msg)
if not msg then return end
self.scrollingMessageFrame:AddMessage(msg)
ChatFrame1:AddMessage(self.scrollingMessageFrame:GetNumRegions() )
end,
['SetText'] = function(self,txt)
-- self.editBox:SetText(txt or '')
end,
}
-- ~~| ScrollingMessageFrame Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
scrollBarButtonHeight = 1,
scrollBarWidth = 6,
contentPadLeft = 0,
contentPadRight = 0,
contentPadTop = 0,
contentPadBottom = 0,
forceScrollBottom = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this) self:FireEvent("OnHide") end)
local scrollFrameContainer = self:CreateRegion("Frame", 'scrollFrameContainer', frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", 'scrollFrame', scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this,delta)
DiesalGUI:OnMouse(this,'MouseWheel')
if delta > 0 then
self:SetVerticalScroll(max( this:GetVerticalScroll() - 50, 0))
else
self:SetVerticalScroll(min( this:GetVerticalScroll() + 50, this:GetVerticalScrollRange()))
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this,offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this,xOffset, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return end
if self.settings.forceScrollBottom then
this:SetVerticalScroll(verticalScrollRange)
else
this:SetVerticalScroll(min(this:GetVerticalScroll(),verticalScrollRange))
end
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this,width,height)
self.scrollingMessageFrame:SetWidth(width)
end)
local scrollingMessageFrame = self:CreateRegion("ScrollingMessageFrame", 'scrollingMessageFrame', scrollFrame)
scrollingMessageFrame:SetPoint("TOPLEFT")
scrollingMessageFrame:SetPoint("TOPRIGHT")
scrollingMessageFrame:SetJustifyH("LEFT")
scrollingMessageFrame:SetJustifyV("TOP")
scrollingMessageFrame:SetInsertMode("BOTTOM")
scrollingMessageFrame:SetMaxLines(500)
scrollingMessageFrame:SetHeight(500)
scrollingMessageFrame:SetFading(false)
scrollFrame:SetScrollChild(scrollingMessageFrame)
local scrollBar = self:CreateRegion("Frame", 'scrollBar', frame)
scrollBar:SetPoint('TOPRIGHT')
scrollBar:SetPoint('BOTTOMRIGHT')
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", 'buttonUp', scrollBar)
buttonUp:SetPoint('TOPLEFT')
buttonUp:SetPoint('TOPRIGHT')
local buttonDown = self:CreateRegion("Frame", 'buttonDown', scrollBar)
buttonDown:SetPoint('BOTTOMLEFT')
buttonDown:SetPoint('BOTTOMRIGHT')
local track = self:CreateRegion("Frame", 'track', scrollBar)
track:SetPoint('LEFT')
track:SetPoint('RIGHT')
track:SetPoint('TOP',buttonUp,'BOTTOM',0,0)
track:SetPoint('BOTTOM',buttonDown,'TOP',0,0)
local grip = self:CreateRegion("Frame", 'grip', track)
grip:SetPoint('LEFT')
grip:SetPoint('RIGHT')
grip:SetPoint('TOP')
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this,button)
DiesalGUI:OnMouse(this,button)
if button ~= 'LeftButton' then return end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5,this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale ))
newGripPosition = min(max(newGripPosition,0),trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
self:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this,button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,294 +0,0 @@
-- $Id: Spinner.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- | Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
local round = DiesalTools.Round
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Spinner |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "Spinner"
local Version = 3
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '000000',
alpha = .6,
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .6,
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .02,
position = 1,
},
['frame-hover'] = {
type = 'outline',
layer = 'HIGHLIGHT',
color = 'FFFFFF',
alpha = .25,
position = -1,
},
['editBox-font'] = {
type = 'Font',
color = Colors.UI_TEXT,
},
['bar-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_A100,ShadeColor(Colors.UI_A100,.1)},
},
['bar-inline'] = {
type = 'outline',
layer = 'BORDER',
gradient = {'VERTICAL','FFFFFF','FFFFFF'},
alpha = {.07,.02},
},
['bar-outline'] = {
type = 'texture',
layer = 'ARTWORK',
color = '000000',
alpha = .7,
width = 1,
position = {nil,1,0,0},
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['editBox-purple'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'aa00ff',
},
['buttonUp-yellow'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'fffc00',
},
['buttonDown-orange'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffd400',
},
['bar-green'] = {
type = 'outline',
layer = 'OVERLAY',
color = '55ff00',
},
}
-- | Internal Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function processNumber(self, number)
local settings = self.settings
local number, oldNumber = tonumber(number), self:GetNumber()
if not number then
number = oldNumber or settings.min
else
number = max(min(number,settings.max),settings.min)
end
settings.number = number
self.editBox:SetText( (settings.prefix or '')..number..(settings.suffix or '') )
self.editBox:HighlightText(0,0) -- clear any selcted text
self.editBox:SetCursorPosition(0)
self:UpdateBar()
if number ~= oldNumber then return number end
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:ApplySettings()
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
local settings = self.settings
local frame = self.frame
local buttonUp = self.buttonUp
local buttonDown = self.buttonDown
local editBox = self.editBox
local buttonsWidth = settings.buttons and settings.buttonsWidth or 0
local buttonHeight = round(settings.height / 2)
-- Apply Settings
self:SetWidth(settings.width)
self:SetHeight(settings.height)
editBox:EnableMouse(settings.mouse)
editBox:EnableMouseWheel(settings.mouseWheel)
editBox:SetPoint('BOTTOMRIGHT',-buttonsWidth,0)
buttonUp[settings.buttons and "Show" or "Hide"](buttonUp)
buttonUp:EnableMouse(settings.mouse)
buttonUp:SetHeight(buttonHeight)
buttonUp:SetWidth(buttonsWidth)
buttonDown[settings.buttons and "Show" or "Hide"](buttonDown)
buttonDown:EnableMouse(settings.mouse)
buttonDown:SetHeight(buttonHeight)
buttonDown:SetWidth(buttonsWidth)
self:UpdateBar()
end,
['EnableMouse'] = function(self,enable)
self.settings.mouse = enable
self.buttonUp:EnableMouse(enable)
self.buttonDown:EnableMouse(enable)
self.editBox:EnableMouse(enable)
self.editBox:EnableMouseWheel(enable)
end,
['GetNumber'] = function(self)
return self.settings.number
end,
['SetNumber'] = function(self,number)
local newNumber = processNumber(self, number)
if newNumber then self:FireEvent("OnValueChanged",false,newNumber) end
end,
['SetPrefix'] = function(self,prefix)
self.settings.prefix = prefix
processNumber(self, self.settings.number)
end,
['SetSuffix'] = function(self,suffix)
self.settings.suffix = suffix
processNumber(self, self.settings.number)
end,
['OnSpin'] = function(self,delta)
local step = IsShiftKeyDown() and self.settings.shiftStep or self.settings.step
local oldNumber = self.settings.number
local newNumber
if delta > 0 then
newNumber = processNumber(self, round(oldNumber,step)+step)
else
newNumber = processNumber(self, round(oldNumber,step)-step)
end
if newNumber then self:FireEvent("OnValueChanged",true,newNumber) end
end,
['UpdateBar'] = function(self)
if not self.settings.bar then return end
local settings = self.settings
local barWidth = self:GetWidth() - (settings.buttons and settings.buttonsWidth or 0) - 2 -- bar padding
local number = settings.number or settings.min
local width = round(((number - settings.min) / (settings.max - settings.min) * barWidth ))
if width == 0 then
self.bar:Hide()
else
self.bar:Show()
self.bar:SetWidth(width)
end
end,
['SetTextColor'] = function(self,color,alpha)
alpha = alpha or 1
color = {DiesalTools.GetColor(color)}
self.editBox:SetTextColor(color[1],color[2],color[3],alpha)
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 16,
width = 29,
mouse = true,
mouseWheel = true,
buttons = false,
buttonsWidth= 8,
bar = true,
min = 0,
max = 100,
step = 5,
shiftStep = 1,
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide",function(this)
self:FireEvent("OnHide")
end)
frame:SetScript('OnSizeChanged', function() self:UpdateBar() end )
local editBox = self:CreateRegion("EditBox", 'editBox', frame)
editBox:SetPoint("TOPLEFT")
editBox:SetAutoFocus(false)
editBox:SetJustifyH("CENTER")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(1,0,2,0)
editBox:SetText(self.defaults.min)
editBox:SetScript('OnEnterPressed', function(this,...)
local number = this:GetNumber() or self.settings.number -- if entered text or nothing revert to old value
local newNumber = processNumber(self, number)
if newNumber then self:FireEvent("OnValueChanged",true,newNumber)end
self:FireEvent("OnEnterPressed",...)
DiesalGUI:ClearFocus()
end)
editBox:HookScript('OnEditFocusLost', function(this,...)
processNumber(self, self.settings.number)
end)
editBox:HookScript('OnEditFocusGained', function(this)
this:SetText( self.settings.number )
this:HighlightText()
end)
editBox:SetScript("OnMouseWheel", function(this,delta)
DiesalGUI:OnMouse(this,'MouseWheel')
self:OnSpin(delta)
end)
editBox:SetScript("OnEnter",function(this,...)
self:FireEvent("OnEnter",...)
end)
editBox:SetScript("OnLeave", function(this,...)
self:FireEvent("OnLeave",...)
end)
local bar = self:CreateRegion("Frame", 'bar', frame)
bar:SetPoint('TOPLEFT',1,-1)
bar:SetPoint('BOTTOMLEFT',-1,1)
local buttonUp = self:CreateRegion("Button", 'buttonUp', frame)
buttonUp:SetPoint('TOP',0,0)
buttonUp:SetPoint('RIGHT')
buttonUp:SetScript("OnClick", function(this)
DiesalGUI:OnMouse(this,button)
PlaySound("gsTitleOptionExit")
self:OnSpin(1)
end)
local buttonDown = self:CreateRegion("Button", 'buttonDown', frame)
buttonDown:SetPoint('BOTTOM',0,0)
buttonDown:SetPoint('RIGHT')
buttonDown:SetScript("OnClick", function(this)
DiesalGUI:OnMouse(this,button)
PlaySound("gsTitleOptionExit")
self:OnSpin(-1)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,174 +0,0 @@
-- $Id: Toggle.lua 60 2018-09-22 08:28:01Z DarkRotations $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
local GetSpellInfo, GetBonusBarOffset, GetDodgeChance = GetSpellInfo, GetBonusBarOffset, GetDodgeChance
local GetPrimaryTalentTree, GetCombatRatingBonus = GetPrimaryTalentTree, GetCombatRatingBonus
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local TYPE = "Toggle"
local VERSION = 1
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = '333333',
alpha = .95,
position = -2
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = '000000',
alpha = .6,
position = -2
},
['frame-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .1,
position = -1,
},
}
local checkBoxStyle = {
base = {
type = 'texture',
layer = 'ARTWORK',
color = '00FF00',
position = -3,
},
disabled = {
type = 'texture',
color = '00FFFF',
},
enabled = {
type = 'texture',
color = Colors.UI_A400,
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self.fontString:SetFontObject("DiesalFontNormal")
self.fontString:SetText()
self:Show()
end,
['OnRelease'] = function(self) end,
['ApplySettings'] = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
["SetChecked"] = function(self,value)
self.settings.checked = value
self.frame:SetChecked(value)
self[self.settings.disabled and "Disable" or "Enable"](self)
end,
["GetChecked"] = function(self)
return self.settings.checked
end,
["Disable"] = function(self)
self.settings.disabled = true
DiesalStyle:StyleTexture(self.check,self.checkBoxStyle and self.checkBoxStyle.disabled or checkBoxStyle.disabled)
self.frame:Disable()
end,
["Enable"] = function(self)
self.settings.disabled = false
DiesalStyle:StyleTexture(self.check,self.checkBoxStyle and self.checkBoxStyle.enabled or checkBoxStyle.enabled)
self.frame:Enable()
end,
["RegisterForClicks"] = function(self,...)
self.frame:RegisterForClicks(...)
end,
["SetText"] = function(self, text)
self.fontString:SetText(text)
end,
}
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(TYPE)
local frame = CreateFrame('CheckButton', nil, UIParent)
local fontString = frame:CreateFontString()
self.frame = frame
self.fontString = fontString
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 11,
width = 11,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnValueChanged, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local check = self:CreateRegion("Texture", 'check', frame)
self.check = check
DiesalStyle:StyleTexture(check,self.checkBoxStyle and self.checkBoxStyle.base or checkBoxStyle.base)
frame:SetCheckedTexture(check)
frame:SetScript('OnClick', function(this,button,...)
DiesalGUI:OnMouse(this,button)
if not self.settings.disabled then
self:SetChecked(not self.settings.checked)
if self.settings.checked then
----PlaySound("igMainMenuOptionCheckBoxOn")
else
----PlaySound("igMainMenuOptionCheckBoxOff")
end
self:FireEvent("OnValueChanged", self.settings.checked)
end
end)
frame:SetScript('OnEnter', function(this)
self:FireEvent("OnEnter")
end)
frame:SetScript('OnLeave', function(this)
self:FireEvent("OnLeave")
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
fontString:SetPoint("TOPLEFT", check, "TOPRIGHT", 5, 2)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(TYPE,Constructor,VERSION)

@ -1,93 +0,0 @@
-- $Id: Tree.lua 60 2016-11-04 01:34:23Z diesal2010 $
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalGUI = LibStub("DiesalGUI-1.0")
local DiesalTools = LibStub("DiesalTools-1.0")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sub, format, match, lower = string.sub, string.format, string.match, string.lower
local tsort = table.sort
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Tree |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "Tree"
local Version = 4
-- ~~| Tree Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['content-background'] = {
type = 'texture',
color = 'ffffff',
alpha = .01,
},
}
-- ~~| Tree Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function collapse(branch)
if branch.Collapse then branch:Collapse() end
if branch.children and next(branch.children) then
for i=1, #branch.children do
collapse(branch.children[i])
end
end
end
-- ~~| Tree Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
-- self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:ApplySettings()
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
end,
['UpdateHeight'] = function(self)
local height = 0
for i=1 , #self.children do
height = height + self.children[i].frame:GetHeight()
end
height = DiesalTools.Round(height)
if self.settings.height ~= height then
self.settings.height = height
self:SetHeight(height)
self:FireEvent("OnHeightChange",height)
end
end,
['CollapseAll'] = function(self, subBranches)
if subBranches then
collapse(self)
else
for i=1, #self.children do
self.children[i]:Collapse()
end
end
end,
['ExpandAll'] = function(self)
for i=1 , #self.children do
self.children[i]:Expand()
end
end,
}
-- ~~| Tree Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = { depth = 0 }
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHeightChange
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local content = self:CreateRegion("Frame", 'content', frame)
content:SetAllPoints()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,387 +0,0 @@
-- $Id: Window.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- | Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.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 = "Window"
local Version = 14
-- ~~| Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-outline'] = {
type = 'outline',
layer = 'BACKGROUND',
color = '000000',
},
['frame-shadow'] = {
type = 'shadow',
},
['titleBar-color'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_400_GR[2],
alpha = .95,
},
-- ['titleBar-background'] = {
-- type = 'texture',
-- layer = 'BACKGROUND',
-- gradient = {'VERTICAL',Colors.UI_400_GR[1],Colors.UI_400_GR[2]},
-- alpha = .95,
-- position = {-1,-1,-1,0},
-- },
['titletext-Font'] = {
type = 'font',
color = 'd8d8d8',
},
['closeButton-icon'] = {
type = 'texture',
layer = 'ARTWORK',
image = {'DiesalGUIcons', {9,5,16,256,128}},
alpha = .3,
position = {-2,nil,-1,nil},
width = 16,
height = 16,
},
['closeButton-iconHover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
image = {'DiesalGUIcons', {9,5,16,256,128}, 'b30000'},
alpha = 1,
position = {-2,nil,-1,nil},
width = 16,
height = 16,
},
['header-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_400_GR[1],Colors.UI_400_GR[2]},
alpha = .95,
position = {0,0,0,-1},
},
['header-inline'] = {
type = 'outline',
layer = 'BORDER',
gradient = {'VERTICAL','ffffff','ffffff'},
alpha = {.05,.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 = .95,
},
['content-outline'] = {
type = 'outline',
layer = 'BORDER',
color = 'FFFFFF',
alpha = .01
},
['footer-background'] = {
type = 'texture',
layer = 'BACKGROUND',
gradient = {'VERTICAL',Colors.UI_400_GR[1],Colors.UI_400_GR[2]},
alpha = .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 = {.05,.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+.5)
else return ceil(num-.5) end
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(sizerWireFrame)
self:Show()
end,
['OnRelease'] = function(self) end,
['SetTopLevel'] = function(self)
DiesalGUI:SetTopLevel(self.frame)
end,
['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:SetMinResize(settings.minWidth,settings.minHeight)
frame:SetMaxResize(settings.maxWidth,settings.maxHeight)
self:UpdatePosition()
self:UpdateSizers()
titleBar:SetHeight(settings.titleBarHeight)
closeButton:SetHeight(settings.titleBarHeight)
closeButton:SetWidth(settings.titleBarHeight)
content:SetPoint("TOPLEFT",settings.padding[1],-(settings.titleBarHeight + headerHeight))
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,
['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,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
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)
frame.obj = self
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:SetPoint("TOPRIGHT", -1, 1)
closeButton:SetScript("OnClick", function(this,button)
DiesalGUI:OnMouse(this,button)
--PlaySound("gsTitleOptionExit")
self:FireEvent("OnClose")
self:Hide()
end)
local titletext = self:CreateRegion("FontString", 'titletext', titleBar)
titletext:SetWordWrap(false)
titletext:SetPoint("TOPLEFT", 4, -5)
titletext:SetPoint("TOPRIGHT", -20, -5)
titletext:SetJustifyH("TOP")
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -0,0 +1,360 @@
local MAJOR, MINOR = "DiesalGUI-2.0", 1
---@alias Diesal.GUI DiesalGUI-2.0
---@class DiesalGUI-2.0
---@field ObjectBase Diesal.GUI.ObjectBase.Methods
---@field ObjectFactory Diesal.GUI.Object.Factory
---@field ObjectVersions Diesal.GUI.Object.Versions
---@field ObjectPool Diesal.GUI.Object.Pool
---@field counts Diesal.GUI.Object.Counts
local DiesalGUI, oldMinor = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalGUI then
return
end
local DiesalGUIDebug = false
local DiesalGUIDebugRedFont = RED_FONT_COLOR or CreateColor(1, 0.12549020349979, 0.12549020349979, 1)
local DiesalGUIDebugWhiteFont = WHITE_FONT_COLOR or CreateColor(1, 1, 1, 1)
local DiesalGUIDebugPrint = function(...)
if not DiesalGUIDebug then
return
end
local args = { ... }
local msgPrefix = DiesalGUIDebugRedFont:WrapTextInColorCode("[DiesalGUI Debug]: ")
local str = ""
for i = 1, #args do
str = str .. tostring(args[i]) .. " "
end
print(msgPrefix .. DiesalGUIDebugWhiteFont:WrapTextInColorCode(str))
end
---@class Diesal.GUI.Padding : { [1]: left, [2]: right, [3]: top, [4]: bottom }
---@alias Diesal.Object.Constructed DiesalAccordian | DiesalAccordianSection | DiesalBar | DiesalBranch | DiesalButton | DiesalCheckBox | DiesalComboBox | DiesalComboBoxItem | DiesalDropDown | DiesalDropDownItem | DiesalInput | DiesalQuickDoc | DiesalScrollFrame | DiesalScrollingEditBox | DiesalScrollingMessageFrame | DiesalSpinner | DiesalText | DiesalTree | DiesalWindow
---@alias Diesal.Container Diesal.GUI.Object.Window | Diesal.GUI.Object.Accordian
---@alias Diesal.Container.Contents DiesalAccordian | DiesalAccordianSection | DiesalBar | DiesalBranch | DiesalButton | DiesalCheckBox | DiesalComboBox | DiesalComboBoxItem | DiesalDropDown | DiesalDropDownItem | FontString | DiesalInput | DiesalQuickDoc | DiesalScrollFrame | DiesalScrollingEditBox | DiesalScrollingMessageFrame | DiesalSpinner | DiesalTree | DiesalText | DiesalWindow | Diesal.GUI.ObjectBase
DiesalGUI.Debug = {
Print = DiesalGUIDebugPrint,
Enabled = DiesalGUIDebug,
RedFont = DiesalGUIDebugRedFont,
WhiteFont = DiesalGUIDebugWhiteFont,
}
local CallbackHandler = LibStub("CallbackHandler-1.0")
local DiesalTools = LibStub("DiesalTools-2.0")
local DiesalStyle = LibStub("DiesalStyle-2.0")
local type, select, tonumber = type, select, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local pairs, ipairs = pairs, ipairs
local tinsert, tremove = table.insert, table.remove
local CreateFrame, UIParent = CreateFrame, UIParent
DiesalGUI.callbacks = DiesalGUI.callbacks or CallbackHandler:New(DiesalGUI)
---@class Diesal.GUI.Object.Factory : { [Diesal.Object.Type]: fun(name?: string): Diesal.Object }
DiesalGUI.ObjectFactory = DiesalGUI.ObjectFactory or {}
---@class Diesal.GUI.Object.Versions : { [Diesal.Object.Type]: number }
DiesalGUI.ObjectVersions = DiesalGUI.ObjectVersions or {}
---@class Diesal.GUI.Object.Pool : { [Diesal.Object.Type]: { [Diesal.Object]: boolean } }
DiesalGUI.ObjectPool = DiesalGUI.ObjectPool or {}
---@class Diesal.GUI.Object.Counts : { [Diesal.Object.Type]: number }
DiesalGUI.counts = DiesalGUI.counts or {}
---@class Diesal.GUI.Object.AntiPool : { [Diesal.Object.Type]: boolean }
DiesalGUI.AntiPool = DiesalGUI.AntiPool or {}
local ObjectFactory = DiesalGUI.ObjectFactory
local ObjectVersions = DiesalGUI.ObjectVersions
local ObjectPool = DiesalGUI.ObjectPool
local function OnMouse(frame, button)
DiesalGUI:ClearFocus()
end
-- Capture mouse clicks on the WorldFrame
---@param frame Frame
---@param button Button
local function WorldFrameOnMouse(frame, button)
OnMouse(frame, button)
end
---@alias Diesal.Object
---|DiesalAccordian
---|DiesalAccordianSection
---|DiesalBar
---|DiesalBranch
---|DiesalButton
---|DGUIBuilder.Container
---|DiesalCheckBox
---|DiesalComboBox
---|DiesalComboBoxItem
---|DiesalDropDown
---|DiesalDropDownItem
---|DiesalInput
---|DiesalObjectBase
---|DiesalQuickDoc
---|DiesalScrollFrame
---|DiesalScrollingEditBox
---|DiesalScrollingMessageFrame
---|DiesalSpinner
---|DiesalText
---|DiesalTree
---|DiesalWindow
---@diagnostic disable-next-line: undefined-field
_G.WorldFrame:HookScript("OnMouseDown", WorldFrameOnMouse)
-- Objects (widgets) that are defined for use in DiesalGUI
---@alias Diesal.Object.Type
---|'"DiesalAccordian"'
---|'"DiesalAccordianSection"'
---|'"DiesalBar"'
---|'"DiesalBranch"'
---|'"DiesalButton"'
---|'"DiesalCheckBox"'
---|'"DiesalComboBox"'
---|'"DiesalComboBoxItem"'
---|'"DiesalDropDown"'
---|'"DiesalDropDownItem"'
---|'"DiesalInput"'
---|'"DiesalObjectBase"'
---|'"DiesalQuickDoc"'
---|'"DiesalScrollFrame"'
---|'"DiesalScrollingEditBox"'
---|'"DiesalScrollingMessageFrame"'
---|'"DiesalSpinner"'
---|'"DiesalText"'
---|'"DiesalTree"'
---|'"DiesalWindow"'
---|'"Container"'
---|'"VerticalLayout"'
-- Returns a new object
---@generic T
---@param objectType `T` | Diesal.Object.Type
---@param base? boolean
---@return T newObj
local function newObject(objectType, base)
if not ObjectFactory[objectType] then
error("Attempt to construct unknown Object type", 2)
end
if base then
return ObjectFactory.DiesalObjectBase(objectType)
end
ObjectPool[objectType] = ObjectPool[objectType] or {}
local newObj = next(ObjectPool[objectType])
if not newObj then
newObj = ObjectFactory[objectType]()
else
ObjectPool[objectType][newObj] = nil
end
return newObj
end
-- Releases an object into ReleasedObjects
---@param obj Diesal.Object
---@param objectType Diesal.Object.Type
local function releaseObject(obj, objectType)
ObjectPool[objectType] = ObjectPool[objectType] or {}
if ObjectPool[objectType][obj] then
error("Attempt to Release Object that is already released", 2)
end
ObjectPool[objectType][obj] = true
end
-- Registers an Object constructor in the ObjectFactory
---@generic T : Diesal.Object.Type
---@param Type `T`
---@param constructor fun(name: string): T
---@param version number
function DiesalGUI:RegisterObjectConstructor(Type, constructor, version)
assert(type(constructor) == "function")
assert(type(version) == "number")
local oldVersion = ObjectVersions[Type]
if oldVersion and oldVersion >= version then
return
end
ObjectVersions[Type] = version
ObjectFactory[Type] = constructor
end
--[[ -- Registers an Object constructor in the ObjectFactory
---@generic T : Diesal.Object.Type
---@param Type `T`
---@param constructor fun(self: Diesal.GUI, type: string | Diesal.Object.Type): Diesal.GUI.ObjectBase
---@param version number
function DiesalGUI:RegisterObjectBaseConstructor(Type, constructor, version)
assert(type(constructor) == "function")
assert(type(version) == "number")
local oldVersion = ObjectVersions[Type]
if oldVersion and oldVersion >= version then
return
end
ObjectVersions[Type] = version
ObjectFactory[Type] = constructor
self.CreateObjectBase = constructor
end ]]
-- Create a new Object
---@generic T
---@param objectType `T` | Diesal.Object.Type
---@param name? string | boolean
---@param methods? table
---@return T object
function DiesalGUI:Create(objectType, name, methods)
local base = (name ~= nil and type(name) == "boolean") and name or nil
local name = (name ~= nil and type(name) == "string") and name or nil
if ObjectFactory[objectType] then
local object
if name then -- needs a specific name, bypass the objectPool and create a new object
object = ObjectFactory[objectType](name)
else
object = newObject(objectType, base)
end
object:SetMethods(methods)
object:ResetSettings()
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if object.OnAcquire then
object:OnAcquire()
end
return object
---@diagnostic disable-next-line: missing-return
end
end
---@param duration number
---@param callback fun(...)
function DiesalGUI:CreateThrottle(duration, callback)
assert(callback and type(callback) == "function", "callback has to be a function ")
assert(duration and type(duration) == "number", "duration has to be a number ")
---@class Throttle : AnimationGroup, Object, FrameScriptObject
local throttle = CreateFrame("Frame", nil, UIParent):CreateAnimationGroup()
throttle.anim = throttle:CreateAnimation("Animation")
throttle.args = {}
local mt = getmetatable(throttle)
---@cast mt Throttle, metatable
mt.__index.SetCallback = function(this, callback)
assert(callback and type(callback) == "function", "callback required to be a function ")
this:SetScript("OnFinished", function()
callback(unpack(this.args))
end)
end
mt.__index.AddCallback = function(this, callback)
assert(callback and type(callback) == "function", "callback required to be a function ")
this:HookScript("OnFinished", function()
callback(unpack(this.args))
end)
end
mt.__index.SetDuration = function(this, callback)
assert(callback and type(callback) == "number", "duration has to be a number ")
this.anim:SetDuration(callback)
end
mt.__call = function(this, ...)
this.args = { ... }
this:Stop()
this:Play()
end
throttle = setmetatable(throttle, mt)
throttle:SetScript("OnFinished", function()
callback(unpack(throttle.args))
end)
throttle:SetDuration(duration)
return throttle
end
---@param object Diesal.Object
function DiesalGUI:Release(object)
if object.OnRelease then
object:OnRelease()
end
object:FireEvent("OnRelease")
object:ReleaseChildren()
object:ReleaseTextures()
object:ResetFonts()
object:ResetEventListeners()
object.frame:ClearAllPoints()
object.frame:Hide()
object.frame:SetParent(UIParent)
releaseObject(object, object.type)
end
---@alias Diesal.GUI.Object.Focusable
---|Diesal.GUI.Object.ComboBox
---|Diesal.GUI.Object.DropDown
-- Set FocusedObject: Menu, Dropdown, editBox etc....
---@param object Diesal.GUI.Object.Focusable
function DiesalGUI:SetFocus(object)
if self.FocusedObject and self.FocusedObject ~= object then
DiesalGUI:ClearFocus()
end
self.FocusedObject = object
end
-- Clear focus from the FocusedObject
function DiesalGUI:ClearFocus()
local FocusedObject = self.FocusedObject
if FocusedObject then
if FocusedObject.ClearFocus then -- FocusedObject is Focusable Frame
FocusedObject:ClearFocus()
end
self.FocusedObject = nil
end
end
-- Mouse Input capture for any DiesalGUI interactive region
---@param frame Frame
---@param button MouseButton | "MouseWheel"
function DiesalGUI:OnMouse(frame, button)
-- print(button)
OnMouse(frame, button)
DiesalGUI.callbacks:Fire("DiesalGUI_OnMouse", frame, button)
end
--- A type-based counter to count the number of widgets created.
---@param objectType Diesal.Object.Type
function DiesalGUI:GetNextObjectNum(objectType)
if not self.counts[objectType] then
self.counts[objectType] = 0
end
self.counts[objectType] = self.counts[objectType] + 1
return self.counts[objectType]
end
--- Return the number of created widgets for this type.
---@param objectType Diesal.Object.Type
function DiesalGUI:GetObjectCount(objectType)
return self.counts[objectType] or 0
end

@ -0,0 +1,25 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
<Script file="DiesalGUI-2.0.lua" />
<!-- Objects -->
<Script file="Objects\ObjectBase.lua" />
<Script file="Objects\Window.lua" />
<Script file="Objects\ScrollFrame.lua" />
<Script file="Objects\ScrollingEditBox.lua" />
<Script file="Objects\ScrollingMessageFrame.lua" />
<Script file="Objects\CheckBox.lua" />
<Script file="Objects\Button.lua" />
<Script file="Objects\Spinner.lua" />
<Script file="Objects\Input.lua" />
<Script file="Objects\Dropdown.lua" />
<Script file="Objects\DropdownItem.lua" />
<Script file="Objects\ComboBox.lua" />
<Script file="Objects\ComboBoxItem.lua" />
<Script file="Objects\Accordian.lua" />
<Script file="Objects\AccordianSection.lua" />
<Script file="Objects\Text.lua" />
<Script file="Objects\Tree.lua" />
<Script file="Objects\Branch.lua" />
<Script file="Objects\Bar.lua" />
<Script file="Objects\Toggle.lua" />
</Ui>

@ -0,0 +1,82 @@
---@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 = "DiesalAccordian"
local Version = 2
---@type Diesal.Style.Stylesheet
local Stylesheet = {
["frame-background"] = {
type = "texture",
color = "FF0000",
},
}
---@class Diesal.GUI.Accordian.Methods
local methods = {
---@param self DiesalAccordian
OnAcquire = function(self)
-- self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:ResetSettings(true)
self:Show()
end,
---@param self DiesalAccordian
OnRelease = function(self) end,
---@param self DiesalAccordian
ApplySettings = function(self) end,
---@param self DiesalAccordian
CollapseAll = function(self)
for i = 1, #self.children do
self.children[i]:Collapse()
end
end,
---@param self DiesalAccordian
ExpandAll = function(self)
for i = 1, #self.children do
self.children[i]:Expand()
end
end,
}
---@class DiesalAccordian : Diesal.GUI.Object.Accordian
local function Constructor()
---@class Diesal.GUI.Object.Accordian : Diesal.GUI.ObjectBase, Diesal.GUI.Accordian.Methods
---@field content Frame
---@field children DiesalAccordianSection[]
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
self.defaults = {}
-- Events
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHeightChange
local content = self:CreateRegion("Frame", "content", frame)
content:SetAllPoints()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,264 @@
---@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
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
local Type = "DiesalAccordianSection"
local Version = 3
---@type Diesal.Style.Stylesheet
local Stylesheet = {
["button-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 },
},
["button-outline"] = {
type = "outline",
layer = "BACKGROUND",
color = "000000",
position = { 1, 1, 0, 1 },
},
["button-inline"] = {
type = "outline",
layer = "ARTWORK",
gradient = { "VERTICAL", "ffffff", "ffffff" },
alpha = { 0.03, 0.02 },
position = { 0, 0, -1, 0 },
},
["button-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.1,
},
["button-leftExpandIcon"] = {
type = "texture",
position = { 0, nil, -1, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 3, 6, 16, 256, 128 }, HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.65) },
alpha = 1,
},
["button-leftCollapseIcon"] = {
type = "texture",
position = { 0, nil, -1, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 4, 6, 16, 256, 128 }, HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.65) },
alpha = 1,
},
["content-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_300,
alpha = 0.95,
position = { 0, 0, -1, 0 },
},
["content-topShadow"] = {
type = "texture",
layer = "ARTWORK",
gradient = { "VERTICAL", "000000", "000000" },
alpha = { 0.05, 0 },
position = { 0, 0, -1, nil },
height = 4,
},
["content-bottomShadow"] = {
type = "texture",
layer = "ARTWORK",
gradient = { "VERTICAL", "000000", "000000" },
alpha = { 0, 0.05 },
position = { 0, 0, nil, 0 },
height = 4,
},
["content-inline"] = {
type = "outline",
layer = "ARTWORK",
color = "ffffff",
alpha = 0.02,
position = { 0, 0, -1, 0 },
},
["text-Font"] = {
type = "font",
color = Colors.UI_F450,
},
}
local wireFrameSheet = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
alpha = 1,
},
["button-purple"] = {
type = "outline",
layer = "OVERLAY",
color = "aa00ff",
alpha = 0.5,
},
["content-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "fffc00",
alpha = 0.5,
},
}
---@class Diesal.GUI.Accordian.Section.Methods
local methods = {
---@param self DiesalAccordianSection
OnAcquire = function(self)
self:SetStylesheet(Stylesheet)
self:Show()
end,
---@param self DiesalAccordianSection
OnRelease = function(self) end,
---@param self DiesalAccordianSection
ApplySettings = function(self)
self.button:SetHeight(self.settings.buttonHeight)
-- postion
self:ClearAllPoints()
if self.settings.position == 1 then
self:SetPoint("TOPLEFT")
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
-- set section name
self.text:SetText(self.settings.sectionName)
-- set section state
self[self.settings.expanded and "Expand" or "Collapse"](self)
-- set button visibility
self:SetButton(self.settings.button)
end,
---@param self DiesalAccordianSection
Collapse = function(self)
if not self.settings.button then
self:UpdateHeight()
return
end
self.settings.expanded = false
self:FireEvent("OnStateChange", self.settings.position, "Collapse")
self.textures["button-leftCollapseIcon"]:SetAlpha(self.textures["button-leftCollapseIcon"].style.alpha[1])
self.textures["button-leftExpandIcon"]:SetAlpha(0)
self.content:Hide()
self:UpdateHeight()
end,
---@param self DiesalAccordianSection
Expand = function(self)
self.settings.expanded = true
self:FireEvent("OnStateChange", self.settings.position, "Expand")
self.textures["button-leftExpandIcon"]:SetAlpha(self.textures["button-leftExpandIcon"].style.alpha[1])
self.textures["button-leftCollapseIcon"]:SetAlpha(0)
self.content:Show()
self:UpdateHeight()
end,
---@param self DiesalAccordianSection
---@param state boolean
SetButton = function(self, state)
self.settings.button = state
self.button[state and "Show" or "Hide"](self.button)
if not state then
self:Expand()
else
self:UpdateHeight()
end
end,
---@param self DiesalAccordianSection | Diesal.GUI.Object.Accordian.Section
UpdateHeight = function(self)
local settings, children = self.settings, self.children
local contentHeight = 0
self.content:SetPoint("TOPLEFT", self.frame, 0, settings.button and -settings.buttonHeight or 0)
if settings.expanded then
contentHeight = settings.contentPadding[3] + settings.contentPadding[4]
for i = 1, #children do
contentHeight = contentHeight + children[i].frame:GetHeight()
end
end
self.content:SetHeight(contentHeight)
self:SetHeight((settings.button and settings.buttonHeight or 0) + contentHeight)
self:FireEvent("OnHeightChange", contentHeight)
end,
}
---@class DiesalAccordianSection : Diesal.GUI.Object.Accordian.Section
---@class Diesal.GUI.Object.Accordian.Section.Settings.Default
---@field button boolean
---@field contentPadding Diesal.GUI.Padding
---@field expanded boolean
---@field buttonHeight number
---@class Diesal.GUI.Object.Accordian.Section.Settings : Diesal.GUI.Object.Accordian.Section.Settings.Default
---@field sectionName string
---@field position number
---@field parentObject Diesal.GUI.Object.Accordian
local function Constructor()
---@class Diesal.GUI.Object.Accordian.Section : Diesal.GUI.ObjectBase, Diesal.GUI.Accordian.Section.Methods
---@field button Button
---@field text Diesal.GUI.Region.FontString
---@field content Frame
---@field settings Diesal.GUI.Object.Accordian.Section.Settings
---@field defaults Diesal.GUI.Object.Accordian.Section.Settings.Default
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
self.defaults = {
button = true,
contentPadding = { 0, 0, 3, 1 },
expanded = true,
buttonHeight = 16,
}
local button = self:CreateRegion("Button", "button", frame)
button:SetPoint("TOPRIGHT")
button:SetPoint("TOPLEFT")
button:SetScript("OnClick", function(this, b)
DiesalGUI:OnMouse(this, b)
self[self.settings.expanded and "Collapse" or "Expand"](self)
end)
local text = self:CreateRegion("FontString", "text", button)
text:SetPoint("TOPLEFT", 15, -2)
text:SetPoint("BOTTOMRIGHT", -15, 0)
text:SetHeight(0)
text:SetJustifyH("MIDDLE")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local content = self:CreateRegion("Frame", "content", frame)
content:SetPoint("TOPLEFT", frame, 0, 0)
content:SetPoint("TOPRIGHT", frame, 0, 0)
content:SetHeight(10)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,205 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Spinner |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalBar"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.60,
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
position = 1,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.60,
},
["bar-background"] = {
type = "texture",
layer = "BACKGROUND",
gradient = { "VERTICAL", Colors.UI_A100, ShadeColor(Colors.UI_A100, 0.1) },
position = 0,
},
["bar-inline"] = {
type = "outline",
layer = "BORDER",
gradient = { "VERTICAL", "FFFFFF", "FFFFFF" },
alpha = { 0.07, 0.02 },
position = 0,
},
["bar-outline"] = {
type = "texture",
layer = "ARTWORK",
color = "000000",
alpha = 0.7,
width = 1,
position = { nil, 1, 0, 0 },
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["bar-green"] = {
type = "outline",
layer = "OVERLAY",
color = "55ff00",
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function round(num)
return floor((num + 1 / 2) / 1) * 1
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Object.Bar.Methods
---@field OnAcquire fun(self: Diesal.GUI.Object.Bar)
---@field OnRelease fun(self: Diesal.GUI.Object.Bar)
---@field ApplySettings fun(self: Diesal.GUI.Object.Bar)
---@field UpdateSize fun(self: Diesal.GUI.Object.Bar)
---@field SetColor fun(self: Diesal.GUI.Object.Bar, color: string, colorTop: string, gradientDirection: string)
---@field SetSize fun(self: Diesal.GUI.Object.Bar, width: number, height: number)
---@field SetValue fun(self: Diesal.GUI.Object.Bar, number: number, min: number, max: number)
---@field SetMin fun(self: Diesal.GUI.Object.Bar, number: number)
---@field SetMax fun(self: Diesal.GUI.Object.Bar, number: number)
---@field UpdateBar fun(self: Diesal.GUI.Object.Bar)
---@field IsVisible fun(self: Diesal.GUI.Object.Bar): boolean
local methods = {
["OnAcquire"] = function(self)
self:SetStylesheet(Stylesheet)
self:ApplySettings()
-- self:SetStylesheet(wireFrame)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
self:UpdateSize()
end,
["UpdateSize"] = function(self)
self:SetWidth(self.settings.width)
self:SetHeight(self.settings.height)
self.bar:SetPoint("TOPLEFT", self.settings.padding[1], -self.settings.padding[3])
self.bar:SetPoint("BOTTOMLEFT", self.settings.padding[1], self.settings.padding[4])
self.settings.barWidth = self.settings.width - self.settings.padding[1] - self.settings.padding[2]
self:UpdateBar()
end,
["SetColor"] = function(self, color, colorTop, gradientDirection) end,
["SetSize"] = function(self, width, height)
width, height = tonumber(width), tonumber(height)
if not width then
error("Bar:SetSize(width, height) width to be a number.", 0)
end
if not height then
error("Bar:SetSize(width, height) height to be a number.", 0)
end
self.settings.width, self.settings.height = width, height
self:UpdateSize()
end,
["SetValue"] = function(self, number, mi, ma)
number, mi, ma = tonumber(number), tonumber(mi), tonumber(ma)
if not number then
error("Bar:SetValue(number) number needs to be a number.", 0)
end
self.settings.min = mi or self.settings.min
self.settings.max = ma or self.settings.max
self.settings.value = number
self:UpdateBar()
end,
["SetMin"] = function(self, number)
number = tonumber(number)
if not number then
error("Bar:SetMin(number) needs to be a number.", 0)
end
self.settings.min = number
self:UpdateBar()
end,
["SetMax"] = function(self, number)
number = tonumber(number)
if not number then
error("Bar:SetMax(number) needs to be a number.", 0)
end
self.settings.max = number
self:UpdateBar()
end,
["UpdateBar"] = function(self)
local min, max, value, barWidth = self.settings.min, self.settings.max, self.settings.value, self.settings.barWidth
local width = round((value - min) / (max - min) * barWidth)
if width == 0 then
self.bar:Hide()
else
self.bar:Show()
self.bar:SetWidth(width)
end
end,
["IsVisible"] = function(self)
return self.frame:IsVisible()
end,
}
---@class DiesalBar : Diesal.GUI.Object.Bar
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Bar : Diesal.GUI.ObjectBase, Diesal.GUI.Object.Bar.Methods
---@field bar Frame
---@field settings { height: number, width: number, padding: number[], value: number, min: number, max: number, barWidth: number }
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 14, -- frame height (not bar)
width = 96, -- frame width (not bar)
padding = { 1, 1, 1, 1 }, -- left, right, top, bottom (bar padding from frame)
value = 0,
min = 0,
max = 100,
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
local bar = self:CreateRegion("Frame", "bar", frame)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,341 @@
---@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, 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, {
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)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,127 @@
---@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 type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
local GetSpellInfo, GetBonusBarOffset, GetDodgeChance = GetSpellInfo, GetBonusBarOffset, GetDodgeChance
local GetCombatRatingBonus = GetCombatRatingBonus
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalButton"
local Version = 5
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["text-color"] = {
type = "Font",
color = "b8c2cc",
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Button.Methods
---@field OnAcquire fun(self: Diesal.GUI.Object.Button)
---@field OnRelease fun(self: Diesal.GUI.Object.Button)
---@field ApplySettings fun(self: Diesal.GUI.Object.Button): boolean | nil
---@field SetText fun(self: Diesal.GUI.Object.Button, text: string)
---@field Disable fun(self: Diesal.GUI.Object.Button)
---@field Enable fun(self: Diesal.GUI.Object.Button)
---@field RegisterForClicks fun(self: Diesal.GUI.Object.Button, ...)
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
["SetText"] = function(self, text)
self.text:SetText(text)
end,
["Disable"] = function(self)
self.settings.disabled = true
self.frame:Disable()
end,
["Enable"] = function(self)
self.settings.disabled = false
self.frame:Enable()
end,
["RegisterForClicks"] = function(self, ...)
self.frame:RegisterForClicks(...)
end,
}
---@class DiesalButton : Diesal.GUI.Object.Button
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor(name)
---@class Diesal.GUI.Object.Button : Diesal.GUI.ObjectBase, Diesal.GUI.Button.Methods
---@field text Diesal.GUI.Region.FontString
---@field settings { disabled: boolean, height: number, width: number }
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Button", name, UIParent)
self.frame = frame
self.defaults = {
height = 32,
width = 32,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnClick, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local text = self:CreateRegion("FontString", "text", frame)
text:SetPoint("TOPLEFT", 4, -1) -- sits below center when rendered off by 1 pixel, fuck you blizzard
text:SetPoint("BOTTOMRIGHT", -4, 0)
text:SetJustifyV("MIDDLE")
text:SetJustifyH("CENTER")
frame:SetFontString(text)
---@param this Button
---@param button MouseButton
frame:SetScript("OnClick", function(this, button, ...)
DiesalGUI:OnMouse(this, button)
self:FireEvent("OnClick", button, ...)
end)
frame:SetScript("OnEnter", function(this)
self:FireEvent("OnEnter")
end)
frame:SetScript("OnLeave", function(this)
self:FireEvent("OnLeave")
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,190 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
local GetSpellInfo, GetBonusBarOffset, GetDodgeChance = GetSpellInfo, GetBonusBarOffset, GetDodgeChance
local GetCombatRatingBonus = GetCombatRatingBonus
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalCheckBox"
local Version = 1
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.60,
position = -2,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.6,
position = -2,
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
position = -1,
},
}
local checkBoxStyle = {
base = {
type = "texture",
layer = "ARTWORK",
color = Colors.UI_A400,
position = -3,
},
disabled = {
type = "texture",
color = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.35),
},
enabled = {
type = "texture",
color = Colors.UI_A400,
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.CheckBox.Settings
---@field height number
---@field width number
---@field checked boolean
---@field disabled boolean
---@class Diesal.GUI.CheckBox.Methods
local methods = {
---@param self Diesal.GUI.Object.CheckBox
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
---@param self Diesal.GUI.Object.CheckBox
["OnRelease"] = function(self) end,
---@param self Diesal.GUI.Object.CheckBox
["ApplySettings"] = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
---@param self Diesal.GUI.Object.CheckBox
---@param value boolean
["SetChecked"] = function(self, value)
self.settings.checked = value
self.frame:SetChecked(value)
self.value = self.settings.checked
self[self.settings.disabled and "Disable" or "Enable"](self)
end,
["GetChecked"] = function(self)
return self.settings.checked
end,
["Disable"] = function(self)
self.settings.disabled = true
DiesalStyle:StyleTexture(self.check, checkBoxStyle.disabled)
self.frame:Disable()
end,
["Enable"] = function(self)
self.settings.disabled = false
DiesalStyle:StyleTexture(self.check, checkBoxStyle.enabled)
self.frame:Enable()
end,
["RegisterForClicks"] = function(self, ...)
self.frame:RegisterForClicks(...)
end,
}
---@class DiesalCheckBox : Diesal.GUI.Object.CheckBox
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.CheckBox : Diesal.GUI.ObjectBase, Diesal.GUI.CheckBox.Methods
---@field check Texture
---@field settings Diesal.GUI.CheckBox.Settings
---@field value boolean
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("CheckButton", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 11,
width = 11,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnValueChanged, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local check = self:CreateRegion("Texture", "check", frame)
DiesalStyle:StyleTexture(check, checkBoxStyle.base)
frame:SetCheckedTexture(check)
frame:SetScript("OnClick", function(this, button, ...)
DiesalGUI:OnMouse(this, button)
if not self.settings.disabled then
self:SetChecked(not self.settings.checked)
if self.settings.checked then
PlaySound(856)
else
PlaySound(857)
end
self:FireEvent("OnValueChanged", self.settings.checked)
end
end)
frame:SetScript("OnEnter", function(this)
self:FireEvent("OnEnter")
end)
frame:SetScript("OnLeave", function(this)
self:FireEvent("OnLeave")
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,314 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local sub, format, lower, upper, gsub = string.sub, string.format, string.lower, string.upper, string.gsub
local tsort = table.sort
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBox |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalComboBox"
local Version = 1
-- ~~| ComboBox Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.7,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.7,
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
position = 1,
},
["button-background"] = {
type = "texture",
layer = "BACKGROUND",
gradient = { "VERTICAL", Colors.UI_500_GR[1], Colors.UI_500_GR[2] },
},
["button-outline"] = {
type = "outline",
layer = "ARTWORK",
color = "000000",
alpha = 0.9,
},
["button-inline"] = {
type = "outline",
layer = "BORDER",
gradient = { "VERTICAL", "FFFFFF", "FFFFFF" },
alpha = { 0.07, 0.02 },
position = -1,
},
["button-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.05,
},
["button-arrow"] = {
type = "texture",
layer = "BORDER",
image = { "DiesalGUIcons", { 2, 1, 16, 256, 128 } },
alpha = 0.5,
position = { nil, -4, -5, nil },
height = 4,
width = 5,
},
["editBox-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.1,
position = { -1, 0, -1, -1 },
},
["editBox-font"] = {
type = "Font",
color = Colors.UI_TEXT,
},
["dropdown-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_100,
alpha = 0.95,
},
["dropdown-inline"] = {
type = "outline",
layer = "BORDER",
color = "ffffff",
alpha = 0.02,
position = -1,
},
["dropdown-shadow"] = {
type = "shadow",
},
}
-- ~~| ComboBox Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a, b)
return a.value < b.value
end
local function sortList(list, orderedKeys)
if orderedKeys then
return orderedKeys
end
local sortedList = {}
local orderedKeys = {}
for key, value in pairs(list) do
sortedList[#sortedList + 1] = { key = key, value = value }
end
tsort(sortedList, compare)
for i, value in ipairs(sortedList) do
orderedKeys[#orderedKeys + 1] = value.key
end
return orderedKeys
end
-- ~~| ComboBox Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.ComboBox.Methods
---@field OnAcquire fun(self: Diesal.GUI.Object.ComboBox)
---@field OnRelease fun(self: Diesal.GUI.Object.ComboBox)
---@field ApplySettings fun(self: Diesal.GUI.Object.ComboBox): boolean | nil
---@field SetList fun(self: Diesal.GUI.Object.ComboBox, list: table, orderedKeys: table)
---@field SetValue fun(self: Diesal.GUI.Object.ComboBox, key: string)
---@field SetText fun(self: Diesal.GUI.Object.ComboBox, text: string)
---@field SetJustify fun(self: Diesal.GUI.Object.ComboBox, j: string)
---@field SetFocus fun(self: Diesal.GUI.Object.ComboBox)
---@field ClearFocus fun(self: Diesal.GUI.Object.ComboBox)
---@field ClearSelection fun(self: Diesal.GUI.Object.ComboBox)
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
local settings = self.settings
local content = self.content
local frame = self.frame
local children = self.children
local dropdown = self.dropdown
frame:SetWidth(settings.width)
frame:SetHeight(settings.height)
self.editBox:SetPoint("RIGHT", -settings.buttonWidth, 0)
self.button:SetWidth(settings.buttonWidth)
-- dropdown
content:SetPoint("TOPLEFT", settings.dropdownPadding[1], -settings.dropdownPadding[3])
content:SetPoint("BOTTOMRIGHT", -settings.dropdownPadding[2], settings.dropdownPadding[4])
local menuHeight = 0
for i = 1, #children do
menuHeight = menuHeight + children[i].frame:GetHeight()
end
dropdown:SetHeight(settings.dropdownPadding[3] + menuHeight + settings.dropdownPadding[4])
end,
["SetList"] = function(self, list, orderedKeys)
self:ReleaseChildren()
self:SetText("")
local settings = self.settings
local orderedKeys = sortList(list, orderedKeys)
settings.list = list
for position, key in ipairs(orderedKeys) do
local comboBoxItem = DiesalGUI:Create("DiesalComboBoxItem") --[[ @asDiesal.GUI.Object.ComboBox.Itemm ]]
self:AddChild(comboBoxItem)
comboBoxItem:SetParentObject(self)
comboBoxItem:SetSettings({
key = key,
value = list[key],
position = position,
}, true)
end
self:ApplySettings()
end,
["SetValue"] = function(self, key)
for i = 1, #self.children do
self.children[i]:SetSelected(false)
end
for i = 1, #self.children do
if self.children[i].settings.key == key then
self.children[i]:SetSelected(true)
self:SetText(self.children[i].settings.value)
self.editBox:SetCursorPosition(0)
break
end
end
end,
["SetText"] = function(self, text)
self.editBox:SetText(text)
end,
["SetJustify"] = function(self, j)
self.editBox:SetJustifyH(j)
end,
["SetFocus"] = function(self)
DiesalGUI:SetFocus(self)
end,
["ClearFocus"] = function(self)
self.dropdown:Hide()
end,
["ClearSelection"] = function(self)
for i = 1, #self.children do
self.children[i]:SetSelected(false)
end
self:SetText("")
end,
}
---@class DiesalComboBox : Diesal.GUI.Object.ComboBox
-- ~~| ComboBox Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.ComboBox : Diesal.GUI.ObjectBase, Diesal.GUI.ComboBox.Methods
---@field editBox Diesal.GUI.Region.EditBox
---@field button Button
---@field dropdown Frame
---@field content Frame
---@field children Diesal.GUI.Object.ComboBox.Item[]
---@field settings { width: number, height: number, buttonWidth: number, dropdownPadding: table, dropdownButtonWidth: number, list: table, selectedKey: string, selectedValue: string, oldValue: string}
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
width = 100,
height = 16,
buttonWidth = 16,
dropdownPadding = { 4, 4, 4, 4 },
dropdownButtonWidth = 16,
}
-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnValueSelected, OnRenameValue
-- OnEnter, OnLeave
-- OnButtonClick, OnButtonEnter, OnButtonLeave
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local editBox = self:CreateRegion("EditBox", "editBox", frame)
editBox:SetPoint("TOPLEFT")
editBox:SetPoint("BOTTOMLEFT")
editBox:SetAutoFocus(false)
editBox:SetJustifyH("RIGHT")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(1, 2, 2, 0)
editBox:SetScript("OnEnterPressed", function(this)
local text = this:GetText()
DiesalGUI:ClearFocus()
if text ~= self.settings.oldValue then
self:FireEvent("OnRenameValue", self.settings.selectedKey, text)
end
end)
editBox:HookScript("OnEscapePressed", function(this, ...)
this:SetText(self.settings.oldValue)
end)
editBox:HookScript("OnEditFocusGained", function(this)
self.settings.oldValue = this:GetText()
end)
editBox:HookScript("OnEditFocusLost", function(this, ...)
self:SetText(self.settings.oldValue)
end)
editBox:SetScript("OnEnter", function(this)
self:FireEvent("OnEnter")
end)
editBox:SetScript("OnLeave", function(this)
self:FireEvent("OnLeave")
end)
local button = self:CreateRegion("Button", "button", frame)
button:SetPoint("TOPRIGHT")
button:SetPoint("BOTTOMRIGHT")
button:SetScript("OnEnter", function(this)
self:FireEvent("OnButtonEnter")
end)
button:SetScript("OnLeave", function(this)
self:FireEvent("OnButtonLeave")
end)
---@param this Button
---@param b MouseButton
button:SetScript("OnClick", function(this, b)
self:FireEvent("OnButtonClick")
local dropdown = self.dropdown
local visible = dropdown:IsVisible()
DiesalGUI:OnMouse(this, b)
dropdown[visible and "Hide" or "Show"](dropdown)
end)
local dropdown = self:CreateRegion("Frame", "dropdown", frame)
dropdown:SetFrameStrata("FULLSCREEN_DIALOG")
dropdown:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, -2)
dropdown:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, -2)
dropdown:SetScript("OnShow", function(this)
this:SetFocus()
end)
dropdown:Hide()
self:CreateRegion("Frame", "content", dropdown)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,145 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBoxItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalComboBoxItem"
local Version = 2
-- ~~| ComboBoxItem Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "b3d9ff",
alpha = 0.05,
},
}
-- ~~| ComboBoxItem Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ComboBoxItem Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.ComboBoxItem.Methods
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
["OnRelease"] = function(self)
self.check:Hide()
end,
["ApplySettings"] = function(self)
if not self.settings.key then
return
end
local settings = self.settings
local comboBoxSettings = settings.parentObject.settings
local text = self.text
if settings.position == 1 then
self:SetPoint("TOPLEFT")
self:SetPoint("RIGHT")
else
self:SetPoint("TOPLEFT", settings.parentObject.children[settings.position - 1].frame, "BOTTOMLEFT", 0, 0)
self:SetPoint("RIGHT")
end
self:SetHeight(comboBoxSettings.dropdownButtonWidth)
self:SetText(settings.value)
end,
["SetText"] = function(self, text)
self.text:SetText(text)
end,
["OnClick"] = function(self)
local settings = self.settings
local comboBox = settings.parentObject
local comboBoxSettings = comboBox.settings
local comboBoxItems = comboBox.children
for i = 1, #comboBoxItems do
comboBoxItems[i]:SetSelected(false)
end
self:SetSelected(true)
comboBox.dropdown:Hide()
comboBox:SetText(settings.value)
comboBox:FireEvent("OnValueSelected", settings.key, settings.value)
end,
["SetSelected"] = function(self, selected)
if selected then
self.settings.parentObject.settings.selectedKey = self.settings.key
self.settings.selected = true
self.check:Show()
else
self.settings.selected = false
self.check:Hide()
end
end,
}
---@class Diesal.GUI.ComboBoxItem.Settings
---@field parentObject Diesal.GUI.Object.ComboBox
---@field position number
---@field key string
---@field value string
---@field selected boolean
---@class DiesalComboBoxItem : Diesal.GUI.Object.ComboBox.Item
local function Constructor()
---@class Diesal.GUI.Object.ComboBox.Item : Diesal.GUI.ObjectBase, Diesal.GUI.ComboBoxItem.Methods
---@field text FontString
---@field check Texture
---@field settings Diesal.GUI.ComboBoxItem.Settings
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Button", nil, UIParent)
self.frame = frame
self.defaults = {}
frame:SetScript("OnClick", function(this, button)
self:OnClick()
end)
frame:SetScript("OnEnter", function(this) end)
frame:SetScript("OnLeave", function(this) end)
---@type Diesal.GUI.Region.FontString
local text = self:CreateRegion("FontString", "text", frame)
text:SetPoint("TOPLEFT", 12, -2)
text:SetPoint("BOTTOMRIGHT", 0, 0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", "check", frame) --[[ @as Texture ]]
DiesalStyle:StyleTexture(check, {
position = { 2, nil, 0, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 10, 5, 16, 256, 128 }, "FFFF00" },
})
check:Hide()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,404 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local tsort = table.sort
local sub, format, lower, upper, gsub = string.sub, string.format, string.lower, string.upper, string.gsub
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Dropdown |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalDropDown"
local Version = 2
-- ~~| Dropdown Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
gradient = { "VERTICAL", Colors.UI_400_GR[1], Colors.UI_400_GR[2] },
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
gradient = { "VERTICAL", "FFFFFF", "FFFFFF" },
alpha = { 0.07, 0.02 },
position = -1,
},
["frame-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.05,
},
["frame-arrow"] = {
type = "texture",
layer = "BORDER",
image = { "DiesalGUIcons", { 2, 1, 16, 256, 128 } },
alpha = 0.5,
position = { nil, -5, -7, nil },
height = 3,
width = 5,
},
["text-color"] = {
type = "Font",
color = Colors.UI_TEXT,
},
["dropdown-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_100,
alpha = 0.95,
},
["dropdown-inline"] = {
type = "outline",
layer = "BORDER",
color = "ffffff",
alpha = 0.02,
position = -1,
},
["dropdown-shadow"] = {
type = "shadow",
},
}
-- ~~| Dropdown Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a, b)
return a.value < b.value
end
local function sortList(list, orderedKeys)
if orderedKeys then
return orderedKeys
end
local sortedList = {}
local orderedKeys = {}
for key, value in pairs(list) do
sortedList[#sortedList + 1] = { key = key, value = value }
end
tsort(sortedList, compare)
for i, value in ipairs(sortedList) do
orderedKeys[#orderedKeys + 1] = value.key
end
return orderedKeys
end
-- ~~| Dropdown Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.DropDown.Methods
local methods = {
---@param self Diesal.GUI.Object.DropDown
OnAcquire = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
---@param self Diesal.GUI.Object.DropDown
OnRelease = function(self) end,
---@param self Diesal.GUI.Object.DropDown
ApplySettings = function(self)
local settings = self.settings
local content = self.content
local frame = self.frame
local children = self.children
local dropdown = self.dropdown
frame:SetWidth(settings.width)
frame:SetHeight(settings.height)
content:SetPoint("TOPLEFT", dropdown, settings.dropdownPadLeft, -settings.dropdownPadTop)
content:SetPoint("BOTTOMRIGHT", dropdown, -settings.dropdownPadRight, settings.dropdownPadBottom)
local menuHeight = 0
for i = 1, #children do
menuHeight = menuHeight + children[i].frame:GetHeight()
end
dropdown:SetHeight(settings.dropdownPadTop + menuHeight + settings.dropdownPadBottom)
end,
---@param self Diesal.GUI.Object.DropDown
---@param list table
---@param orderedKeys? table
SetList = function(self, list, orderedKeys)
self:ReleaseChildren()
self:SetText("")
local settings = self.settings
--local orderedKeys = sortList(list, orderedKeys)
settings.list = list
local foldColor = "353535"
local expandColor = "5a5a5a"
for position, item in ipairs(list) do
local dropdownItem = DiesalGUI:Create("DiesalDropDownItem")
self:AddChild(dropdownItem)
dropdownItem:SetParentObject(self)
dropdownItem:SetSettings({
key = item.key,
value = item.value,
position = position,
clickable = item.clickable,
indent = item.indent or 0,
}, true)
if item.indent > 0 then
local leftOffset = -6 + (-6 * item.indent)
dropdownItem:UpdateStyle("frame-lineV", {
type = "texture",
layer = "BORDER",
color = foldColor,
position = { leftOffset, nil, -8, nil },
height = 1,
width = 6,
})
dropdownItem:UpdateStyle("frame-lineH", {
type = "texture",
layer = "BORDER",
color = foldColor,
position = { leftOffset, nil, 0, 0 },
width = 1,
})
if item.last then
dropdownItem:UpdateStyle("frame-lineH", {
type = "texture",
position = { leftOffset, nil, 0, -7 },
})
end
end
end
--[[ for position, key in ipairs(orderedKeys) do
---@type Diesal.GUI.Object.DropDown.Item
local dropdownItem = DiesalGUI:Create("DiesalDropDownItem")
self:AddChild(dropdownItem)
dropdownItem:SetParentObject(self)
dropdownItem:SetSettings({
key = key,
value = list[key],
position = position,
}, true)
end ]]
self:ApplySettings()
end,
---@param self Diesal.GUI.Object.DropDown
SetValue = function(self, key)
local selectionTable = {}
local selectedKey, dropdownText, selectedValue
if key ~= "CLEAR" then
if self.settings.multiSelect then
for i = 1, #self.children do
if self.children[i].settings.key == key then
selectedKey = key
self.children[i]:SetSelected(true)
end
if self.children[i].settings.selected then
if dropdownText then
dropdownText = format("%s, %s", dropdownText, self.children[i].settings.value)
else
dropdownText = self.children[i].settings.value
end
selectionTable[#selectionTable + 1] = self.children[i].settings.key
end
end
else
for i = 1, #self.children do
local child = self.children[i]
child:SetSelected(false)
if child.settings.key == key then
child:SetSelected(true)
dropdownText = child.settings.value
selectionTable = { key }
selectedKey = key
selectedValue = self.value
end
end
end
else
self:ClearSelection()
end
if selectedKey then
self:SetText(dropdownText)
self:FireEvent("OnValueChanged", selectedKey, selectedValue, selectionTable)
else
self:SetText("")
self:FireEvent("OnValueChanged", selectedKey, selectedValue, selectionTable)
end
end,
---@param self Diesal.GUI.Object.DropDown
ClearSelection = function(self)
for i = 1, #self.children do
self.children[i]:SetSelected(false)
end
self:SetText("")
end,
---@param self Diesal.GUI.Object.DropDown
SetValueTable = function(self, keyTable)
if not self.settings.multiSelect or type(keyTable) ~= "table" then
return
end
local dropdownItems = self.children
local selectionTable = {}
local selectedKey
local dropdownText
for i = 1, #dropdownItems do
local dropdownItem = dropdownItems[i]
dropdownItem:SetSelected(false)
for _, key in ipairs(keyTable) do
if dropdownItem.settings.key == key then
dropdownItem:SetSelected(true)
dropdownText = dropdownText and format("%s, %s", dropdownText, dropdownItem.settings.value) or dropdownItem.settings.value
selectionTable[#selectionTable + 1] = dropdownItem.settings.key
end
end
end
self:FireEvent("OnValueChanged", nil, nil, selectionTable)
self:SetText(dropdownText)
end,
---@param self Diesal.GUI.Object.DropDown
SetMultiSelect = function(self, state)
self.settings.multiSelect = state
end,
---@param self Diesal.GUI.Object.DropDown
SetText = function(self, text)
self.text:SetText(text)
for i = 1, #self.children do
local child = self.children[i]
if child.settings.value == text then
self.value = child.settings.key
end
end
end,
---@param self Diesal.GUI.Object.DropDown
SetFocus = function(self)
DiesalGUI:SetFocus(self)
end,
---@param self Diesal.GUI.Object.DropDown
ClearFocus = function(self)
self.dropdown:Hide()
end,
---@param self Diesal.GUI.Object.DropDown
EnableMouse = function(self, state)
self.frame:EnableMouse(state)
end,
---@param self Diesal.GUI.Object.DropDown
RegisterForClicks = function(self, ...)
self.frame:RegisterForClicks(...)
end,
---@param self Diesal.GUI.Object.DropDown
SetJustifyV = function(self, justify)
self.text:SetJustifyV(justify)
end,
---@param self Diesal.GUI.Object.DropDown
SetJustifyH = function(self, justify)
self.text:SetJustifyH(justify)
end,
}
---@class Diesal.GUI.Obeject.DropDown.Settings
---@field dropdownPadLeft number
---@field dropdownPadRight number
---@field dropdownPadTop number
---@field dropdownPadBottom number
---@field itemHeight number
---@field width number
---@field height number
---@field list table
---@field multiSelect boolean
---@class DiesalDropDown : Diesal.GUI.Object.DropDown
-- ~~| Dropdown Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.DropDown : Diesal.GUI.ObjectBase, Diesal.GUI.DropDown.Methods
---@field settings Diesal.GUI.Obeject.DropDown.Settings
---@field children Diesal.GUI.Object.DropDown.Item[]
---@field text FontString
---@field dropdown Frame
---@field content Frame
---@field value string
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Button", nil, UIParent)
self.frame = frame
self.isContainer = true
self.defaults = {
dropdownPadLeft = 4,
dropdownPadRight = 4,
dropdownPadTop = 4,
dropdownPadBottom = 4,
itemHeight = 16,
width = 100,
height = 16,
}
-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnValueChanged(event,selectedKey,selectedValue,selectionTable)
-- OnValueSelected(event,selectedKey,selectedValue,selectionTable)
-- OnEnter, OnLeave
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnMouseUp", function(this, button)
if button == "LeftButton" then
local dropdown = self.dropdown
local visible = dropdown:IsVisible()
DiesalGUI:OnMouse(this, button)
dropdown[visible and "Hide" or "Show"](dropdown)
end
end)
frame:SetScript("OnClick", function(this, ...)
self:FireEvent("OnClick", ...)
end)
frame:SetScript("OnEnter", function(this, ...)
self:FireEvent("OnEnter", ...)
end)
frame:SetScript("OnLeave", function(this, ...)
self:FireEvent("OnLeave", ...)
end)
local text = self:CreateRegion("FontString", "text", frame)
text:ClearAllPoints()
text:SetPoint("TOPLEFT", 4, -1)
text:SetPoint("BOTTOMRIGHT", -14, 1)
text:SetJustifyV("MIDDLE")
text:SetJustifyH("LEFT")
local dropdown = self:CreateRegion("Frame", "dropdown", frame)
dropdown:SetFrameStrata("FULLSCREEN_DIALOG")
dropdown:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, -2)
dropdown:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, -2)
dropdown:SetScript("OnShow", function(this)
self:SetFocus()
end)
dropdown:Hide()
self:CreateRegion("Frame", "content", dropdown)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,171 @@
---@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, lower, upper, gsub = string.sub, string.format, string.lower, string.upper, string.gsub
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| DropdownItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalDropDownItem"
local Version = 2
-- ~~| DropdownItem Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "b3d9ff",
alpha = 0.1,
},
}
-- ~~| DropdownItem Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.DropDownItem.Methods
local methods = {
---@param self Diesal.GUI.Object.DropDown.Item
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:Show()
end,
---@param self Diesal.GUI.Object.DropDown.Item
["OnRelease"] = function(self)
self.check:Hide()
end,
---@param self Diesal.GUI.Object.DropDown.Item
["ApplySettings"] = function(self)
if not self.settings.key then
return
end
local settings = self.settings
local dropdownSettings = settings.parentObject.settings
local text = self.text
if settings.position == 1 then
self:SetPoint("TOPLEFT")
else
self:SetPoint("TOPLEFT", settings.parentObject.children[settings.position - 1].frame, "BOTTOMLEFT", 0, 0)
end
self:SetPoint("RIGHT")
self:SetHeight(dropdownSettings.itemHeight)
self:SetText(settings.value)
if settings.clickable == false then
self:UpdateStyle("frame-hover", {
type = "texture",
alpha = 0.0,
})
end
end,
---@param self Diesal.GUI.Object.DropDown.Item
["SetText"] = function(self, text)
local indentText = self.settings.indent == 0 and "" or (" " .. (" "):rep(self.settings.indent) .. " ")
self.text:SetText(indentText .. text)
end,
---@param self Diesal.GUI.Object.DropDown.Item
["OnClick"] = function(self)
local settings = self.settings
local dropdown = settings.parentObject
local dropdownSettings = dropdown.settings
local dropdownItems = dropdown.children
local selectionTable = {}
local dropdownText
print(settings.key, settings.value, settings.clickable)
if not settings.clickable then
return
end
if settings.key ~= "CLEAR" then
if dropdownSettings.multiSelect then
self:SetSelected(not settings.selected)
for i = 1, #dropdownItems do
if dropdownItems[i].settings.selected then
dropdownText = dropdownText and format("%s, %s", dropdownText, dropdownItems[i].settings.value) or dropdownItems[i].settings.value
selectionTable[#selectionTable + 1] = dropdownItems[i].settings.key
end
end
else
for i = 1, #dropdownItems do
if dropdownItems[i].SetSelected then
dropdownItems[i]:SetSelected(false)
end
end
self:SetSelected(true)
dropdownText = settings.value
selectionTable = { settings.key }
dropdown.dropdown:Hide()
end
else
dropdown.dropdown:Hide()
dropdown:ClearSelection()
end
dropdown:SetText(dropdownText)
dropdown:FireEvent("OnValueChanged", settings.key, settings.value, selectionTable)
dropdown:FireEvent("OnValueSelected", settings.key, settings.value, selectionTable)
end,
---@param self Diesal.GUI.Object.DropDown.Item
["SetSelected"] = function(self, selected)
self.settings.selected = selected and true or false
self.check[selected and "Show" or "Hide"](self.check)
end,
}
---@class Diesal.GUI.DropDownItem.Settings : Diesal.GUI.ObjectBase.Settings
---@field key string
---@field value string
---@field position number
---@field selected boolean
---@field clickable boolean
---@field indent number
---@field header boolean
---@class DiesalDropDownItem : Diesal.GUI.Object.DropDown.Item
-- ~~| DropdownItem Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.DropDown.Item : Diesal.GUI.ObjectBase, Diesal.GUI.DropDownItem.Methods
---@field check Texture
---@field text FontString
---@field settings Diesal.GUI.DropDownItem.Settings
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Button", nil, UIParent)
self.frame = frame
self.defaults = {}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnClick", function(this, button)
self:OnClick()
end)
frame:SetScript("OnEnter", function(this) end)
frame:SetScript("OnLeave", function(this) end)
local text = self:CreateRegion("FontString", "text", frame)
text:SetPoint("TOPLEFT", 12, -2)
text:SetPoint("BOTTOMRIGHT", 0, 0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", "check", frame)
DiesalStyle:StyleTexture(check, {
position = { 2, nil, 0, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 10, 5, 16, 256, 128 }, "FFFF00" },
})
check:Hide()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,131 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Input |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalInput"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.6,
},
["editBox-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
position = 1,
},
["editBox-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.7,
},
["editBox-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = "ffffff",
alpha = 0.05,
position = -1,
},
["editBox-font"] = {
type = "Font",
color = Colors.UI_TEXT,
},
}
-- ~~| Spinner Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Input.Methods
local methods = {
["OnAcquire"] = function(self)
self:SetStylesheet(Stylesheet)
self:ApplySettings()
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
self:SetWidth(self.settings.width)
self:SetHeight(self.settings.height)
end,
["GetText"] = function(self)
return self.editBox:GetText()
end,
["SetText"] = function(self, txt)
self.editBox:SetText(txt)
end,
["SetTextColor"] = function(self, color, alpha)
alpha = alpha or 1
color = { DiesalTools.GetColor(color) }
self.editBox:SetTextColor(color[1], color[2], color[3], alpha)
end,
}
---@class DiesalInput : Diesal.GUI.Object.Input
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Input : Diesal.GUI.ObjectBase, Diesal.GUI.Input.Methods
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
self.defaults = {
height = 16,
width = 50,
mouse = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnEnter, OnLeave, OnEnterPressed, OnValueChanged
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
---@type Diesal.GUI.Region.EditBox
local editBox = self:CreateRegion("EditBox", "editBox", frame)
editBox:SetAllPoints()
editBox:SetAutoFocus(false)
editBox:SetJustifyH("LEFT")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(3, 0, 2, 0)
editBox:SetScript("OnEnterPressed", function(this, ...)
self:FireEvent("OnEnterPressed", ...)
DiesalGUI:ClearFocus()
end)
editBox:HookScript("OnEscapePressed", function(this, ...)
self:FireEvent("OnEscapePressed", ...)
end)
editBox:HookScript("OnEditFocusLost", function(this, ...)
self:FireEvent("OnEditFocusLost", ...)
end)
editBox:HookScript("OnEditFocusGained", function(this, ...)
self:FireEvent("OnEditFocusGained", ...)
end)
editBox:SetScript("OnEnter", function(this, ...)
self:FireEvent("OnEnter", ...)
end)
editBox:SetScript("OnLeave", function(this, ...)
self:FireEvent("OnLeave", ...)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,479 @@
---@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 : { defaultFontObject: Font }, FontString
---@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
---@type 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<string, fun(self: self, ...): any>
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
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, ...)
SetEventListener = function(self, event, listener)
if type(listener) == "function" then
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,
--#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()
---@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 ]]

@ -0,0 +1,151 @@
---@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 print, type, select, tostring, tonumber = print, type, select, tostring, tonumber
local sub, format, match, lower = string.sub, string.format, string.match, string.lower
local table_sort = table.sort
local abs = math.abs
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | TableExplorer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalQuickDoc"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local windowStylesheet = {
["content-background"] = {
type = "texture",
color = "131517",
},
}
-- | Local |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local doc = {
{
type = "section",
margin = { 0, 0, 0, 0 },
padding = { 0, 0, 0, 0 },
style = {},
{ type = "single-line", text = "Editor", font = nil, fontSize = 14 },
{ type = "columns", text = "Editor", font = nil, fontSize = 14 },
},
}
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.QuickDoc.Methods
local methods = {
["OnAcquire"] = function(self)
self.settings = DiesalTools.TableCopy(self.defaults)
self:ApplySettings()
self:Show()
end,
["OnRelease"] = function(self)
self.tree:ReleaseChildren()
end,
["ApplySettings"] = function(self) end,
["BuildDoc"] = function(self, doc)
-- if #doc == 0 then error('BuildDoc(doc) doc requires atleast one section')
-- local settings = self.settings
-- -- reset
-- self:ReleaseChildren()
-- -- setup
-- settings.doc = doc
--
-- if #doc == 0 then
-- tree:UpdateHeight()
-- self.statusText:SetText('|cffff0000Table is empty.')
-- return end
-- -- sort tree table
-- local sortedTable = sortTable(settings.exploredTable)
-- -- build Tree Branches
-- for position, key in ipairs(sortedTable) do
-- if self.settings.endtime <= time() then self:Timeout() return end
-- self:BuildBranch(self.tree,key[2],settings.exploredTable[key[2]],position,1,position == #sortedTable)
-- end
end,
["BuildSection"] = function(self, parent, key, value, position, depth, last)
-- local tree = self.tree
-- local leaf = type(value) ~= 'table' or next(value) == nil or depth >= self.settings.maxDepth
-- local branch = DiesalGUI:Create('Branch')
-- -- | Reset Branch |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- branch:ReleaseChildren()
-- -- | setup Branch |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- branch:SetParentObject(parent)
-- parent:AddChild(branch)
-- branch:SetSettings({
-- key = key,
-- value = value,
-- position = position,
-- depth = depth,
-- last = last,
-- leaf = leaf,
-- })
-- branch:SetEventListener('OnClick',function(this,event,button)
-- if button =='RightButton' then
-- if not next(this.settings.menuData) then return end
-- DiesalMenu:Menu(this.settings.menuData,this.frame,10,-10)
-- end
-- end)
--
-- self:SetBranchLabel(branch,key,value,leaf)
-- self:SetBranchMenu(branch,key,value)
-- self:SetBranchIcon(branch,type(value))
--
-- if value == tree or leaf then branch:ApplySettings() return end
-- -- | sort Branch Table |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- local sortedTable = sortTable(value)
-- -- | build Branch Branches |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- for position, key in ipairs(sortedTable) do
-- if self.settings.endtime <= time() then self:Timeout() return end
-- self:BuildBranch(branch,key[2],value[key[2]],position,depth+1,position == #sortedTable)
-- end
-- -- | Update Branch | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- branch:ApplySettings()
end,
["Show"] = function(self)
self.window:Show()
end,
}
---@class DiesalQuickDoc : Diesal.GUI.Object.QuickDoc
-- ~~| TableExplorer Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.QuickDoc : Diesal.GUI.ObjectBase, Diesal.GUI.QuickDoc.Methods
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
self.defaults = {}
---@type Diesal.GUI.Object.Window
local window = DiesalGUI:Create("DiesalWindow")
window:SetSettings({
header = false,
footer = false,
top = UIParent:GetHeight() - 100,
left = 100,
height = 300,
width = 400,
minWidth = 200,
minHeight = 200,
}, true)
window:SetStylesheet(windowStylesheet)
-- ~~ Frames ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.window = window
self.content = window.content
self.frame = window.frame
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,317 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollFrame |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalScrollFrame"
local Version = 3
-- ~~| ScrollFrame Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["track-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.3,
},
["grip-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_400,
},
["grip-inline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["scrollFrameContainer-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "ffff00",
},
["scrollFrame-orange"] = {
type = "outline",
layer = "OVERLAY",
color = "ff7f00",
},
["scrollBar-blue"] = {
type = "outline",
layer = "OVERLAY",
color = "0080ff",
},
["track-green"] = {
type = "outline",
layer = "OVERLAY",
color = "00ff00",
},
["grip-purple"] = {
type = "outline",
layer = "OVERLAY",
color = "a800ff",
},
}
-- ~~| ScrollFrame Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local internal
---@class DiesalScrollFrame : Diesal.GUI.Object.ScrollFrame
-- ~~| ScrollFrame Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.ScrollFrame.Methods
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
--self:SetStylesheet(wireFrame)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
local settings = self.settings
local scrollFrame = self.scrollFrame
scrollFrame:SetPoint("TOPLEFT", settings.contentPadding[1], -settings.contentPadding[3])
scrollFrame:SetPoint("BOTTOMRIGHT", -settings.contentPadding[2], settings.contentPadding[4])
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.scrollBar:SetPoint("TOPRIGHT", -settings.scrollBarPadding[2], -settings.scrollBarPadding[3])
self.scrollBar:SetPoint("BOTTOMRIGHT", -settings.scrollBarPadding[2], settings.scrollBarPadding[4])
if settings.scrollBarButtons then
self.track:SetPoint("TOP", 0, -settings.scrollBarButtonHeight)
self.track:SetPoint("BOTTOM", 0, settings.scrollBarButtonHeight)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:Show()
self.buttonDown:Show()
else
self.track:SetPoint("TOP", 0, 0)
self.track:SetPoint("BOTTOM", 0, 0)
self.buttonUp:Hide()
self.buttonDown:Hide()
end
self.content:SetHeight(settings.contentHeight)
end,
---@param height number
["SetContentHeight"] = function(self, height)
height = height < 1 and 1 or height -- height of 0 wont hide scrollbar
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
["SetGripSize"] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
["SetScrollThumbPosition"] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then
self.grip:SetPoint("TOP", 0, 0)
return
end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint("TOP", 0, -gripPositionOnTrack)
end,
---@param show? boolean
["ShowScrollBar"] = function(self, show)
if show then
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", -(self.settings.scrollBarWidth + self.settings.scrollBarPadding[1] + self.settings.scrollBarPadding[2]), 0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", 0, 0)
end
end,
["ScrollToBottom"] = function(self)
local scrollRange = self.scrollFrame:GetVerticalScrollRange()
if scrollRange > 0 and scrollRange ~= self.scrollFrame:GetVerticalScroll() then
self.scrollFrame:SetVerticalScroll(scrollRange)
end
end,
---@param num number
["SetVerticalScroll"] = function(self, num)
self.scrollFrame:SetVerticalScroll(num)
end,
["GetVerticalScroll"] = function(self)
return self.scrollFrame:GetVerticalScroll()
end,
["GetVerticalScrollRange"] = function(self)
return self.scrollFrame:GetVerticalScrollRange()
end,
---@param num number
["VerticallyScroll"] = function(self, num)
if num < 0 then
self.scrollFrame:SetVerticalScroll(max(self.scrollFrame:GetVerticalScroll() + num, 0))
else
self.scrollFrame:SetVerticalScroll(min(self.scrollFrame:GetVerticalScroll() + num, self.scrollFrame:GetVerticalScrollRange()))
end
end,
}
-- ~~| ScrollFrame Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.ScrollFrame : Diesal.GUI.ObjectBase, Diesal.GUI.ScrollFrame.Methods
---@field scrollFrameContainer Frame
---@field scrollFrame ScrollFrame
---@field content Frame
---@field scrollBar Frame
---@field buttonUp Frame
---@field buttonDown Frame
---@field track Frame
---@field grip Frame
---@field parent Diesal.GUI.Object.Window
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 300,
width = 500,
scrollBarButtonHeight = 4,
scrollBarWidth = 4,
scrollBarButtons = false,
scrollBarPadding = { 0, 0, 0, 0 },
contentPadding = { 0, 0, 0, 0 },
contentHeight = 1,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
local scrollFrameContainer = self:CreateRegion("Frame", "scrollFrameContainer", frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", "scrollFrame", scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this, delta)
DiesalGUI:OnMouse(this, "MouseWheel")
if delta > 0 then
self:VerticallyScroll(-25)
else
self:VerticallyScroll(25)
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this, offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this, horizontalScrollRange, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return
end
this:SetVerticalScroll(min(this:GetVerticalScroll(), verticalScrollRange))
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this, width, height)
self.content:SetWidth(width)
end)
scrollFrame:SetScrollChild(self:CreateRegion("Frame", "content", scrollFrame))
scrollFrame:RegisterForDrag("LeftButton")
scrollFrame:SetScript("OnDragStart", function(this, ...)
self:FireEvent("OnDragStart", ...)
end)
local scrollBar = self:CreateRegion("Frame", "scrollBar", frame)
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", "buttonUp", scrollBar)
buttonUp:SetPoint("TOPLEFT")
buttonUp:SetPoint("TOPRIGHT")
local buttonDown = self:CreateRegion("Frame", "buttonDown", scrollBar)
buttonDown:SetPoint("BOTTOMLEFT")
buttonDown:SetPoint("BOTTOMRIGHT")
local track = self:CreateRegion("Frame", "track", scrollBar)
track:SetPoint("LEFT")
track:SetPoint("RIGHT")
local grip = self:CreateRegion("Frame", "grip", track)
grip:SetPoint("LEFT")
grip:SetPoint("RIGHT")
grip:SetPoint("TOP")
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this, button)
DiesalGUI:OnMouse(this, button)
if button ~= "LeftButton" then
return
end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5, this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale))
newGripPosition = min(max(newGripPosition, 0), trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
scrollFrame:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this, button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,293 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollingEditBox |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalScrollingEditBox"
local Version = 3
-- ~~| ScrollingEditBox Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["track-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.3,
},
["grip-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_400,
},
["grip-inline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["scrollFrameContainer-yellow"] = {
type = "outline",
layer = "BACKGROUND",
color = "fffc00",
},
["scrollFrame-orange"] = {
type = "outline",
layer = "BORDER",
color = "ffd400",
},
["editBox-red"] = {
type = "outline",
layer = "ARTWORK",
color = "ff0000",
aplha = 0.5,
},
["scrollBar-blue"] = {
type = "outline",
layer = "OVERLAY",
color = "00aaff",
},
["track-green"] = {
type = "outline",
layer = "OVERLAY",
color = "55ff00",
},
}
-- ~~| ScrollingEditBox Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| ScrollingEditBox Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.ScrollingEditBox.Methods
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
local settings = self.settings
self.scrollFrame:SetPoint("TOPLEFT", settings.contentPadding[1], -settings.contentPadding[3])
self.scrollFrame:SetPoint("BOTTOMRIGHT", -settings.contentPadding[2], settings.contentPadding[4])
self.scrollBar:SetPoint("TOPRIGHT", 0, -settings.contentPadding[3] + 1)
self.scrollBar:SetPoint("BOTTOMRIGHT", 0, settings.contentPadding[4] - 1)
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
self.editBox:SetJustifyH(settings.justifyH)
self.editBox:SetJustifyV(settings.justifyV)
end,
["ShowScrollBar"] = function(self, show)
if show then
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", -(self.settings.scrollBarWidth + 1), 0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", 0, 0)
end
end,
["SetContentHeight"] = function(self, height)
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
["SetGripSize"] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
["SetScrollThumbPosition"] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then
self.grip:SetPoint("TOP", 0, 0)
return
end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint("TOP", 0, -gripPositionOnTrack)
end,
["SetVerticalScroll"] = function(self, scroll) -- user scrolled only
self.settings.forceScrollBottom = DiesalTools.Round(scroll) == DiesalTools.Round(self.scrollFrame:GetVerticalScrollRange())
self.scrollFrame:SetVerticalScroll(scroll)
end,
["SetText"] = function(self, txt)
self.settings.text = txt
self.value = txt
self.editBox:SetText(txt or "")
end,
}
---@class DiesalScrollingEditBox : Diesal.GUI.Object.ScrollingEditBox
-- ~~| ScrollingEditBox Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.ScrollingEditBox : Diesal.GUI.ObjectBase, Diesal.GUI.ScrollingEditBox.Methods
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
scrollBarButtonHeight = 1,
scrollBarWidth = 4,
contentPadding = { 0, 0, 0, 0 },
justifyH = "LEFT",
justifyV = "TOP",
forceScrollBottom = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
local scrollFrameContainer = self:CreateRegion("Frame", "scrollFrameContainer", frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", "scrollFrame", scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this, delta)
DiesalGUI:OnMouse(this, "MouseWheel")
if delta > 0 then
self:SetVerticalScroll(max(this:GetVerticalScroll() - 50, 0))
else
self:SetVerticalScroll(min(this:GetVerticalScroll() + 50, this:GetVerticalScrollRange()))
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this, offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this, xOffset, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return
end
if self.settings.forceScrollBottom then
this:SetVerticalScroll(verticalScrollRange)
else
this:SetVerticalScroll(min(this:GetVerticalScroll(), verticalScrollRange))
end
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this, width, height)
self.editBox:SetWidth(width)
end)
local editBox = self:CreateRegion("EditBox", "editBox", scrollFrame)
editBox:SetPoint("TOPLEFT")
editBox:SetPoint("TOPRIGHT")
editBox:SetAutoFocus(false)
editBox:SetMultiLine(true)
editBox:HookScript("OnEditFocusLost", function(this)
this:HighlightText(0, 0)
this:SetText(self.settings.text)
end)
editBox:HookScript("OnEditFocusGained", function(this)
self:FireEvent("OnEditFocusGained")
end)
editBox:HookScript("OnEscapePressed", function(this)
self:FireEvent("OnEscapePressed")
end)
editBox:HookScript("OnTabPressed", function(this)
self:FireEvent("OnTabPressed")
end)
editBox:HookScript("OnCursorChanged", function(this, ...)
self:FireEvent("OnCursorChanged", ...)
end)
editBox:HookScript("OnTextChanged", function(this)
self:FireEvent("OnTextChanged")
end)
scrollFrame:SetScrollChild(editBox)
local scrollBar = self:CreateRegion("Frame", "scrollBar", frame)
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", "buttonUp", scrollBar)
buttonUp:SetPoint("TOPLEFT")
buttonUp:SetPoint("TOPRIGHT")
local buttonDown = self:CreateRegion("Frame", "buttonDown", scrollBar)
buttonDown:SetPoint("BOTTOMLEFT")
buttonDown:SetPoint("BOTTOMRIGHT")
local track = self:CreateRegion("Frame", "track", scrollBar)
track:SetPoint("LEFT")
track:SetPoint("RIGHT")
track:SetPoint("TOP", buttonUp, "BOTTOM", 0, 0)
track:SetPoint("BOTTOM", buttonDown, "TOP", 0, 0)
local grip = self:CreateRegion("Frame", "grip", track)
grip:SetPoint("LEFT")
grip:SetPoint("RIGHT")
grip:SetPoint("TOP")
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this, button)
DiesalGUI:OnMouse(this, button)
if button ~= "LeftButton" then
return
end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5, this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale))
newGripPosition = min(max(newGripPosition, 0), trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
self:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this, button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,283 @@
---@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 type, select, pairs, tonumber = type, select, pairs, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper = string.sub, string.format, string.lower, string.upper
local floor, ceil, min, max, abs, modf = math.floor, math.ceil, math.min, math.max, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetCursorPosition = GetCursorPosition
-- ~~| ScrollingMessageFrame |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalScrollingMessageFrame"
local Version = 1
-- ~~| ScrollingMessageFrame Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["track-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "0e0e0e",
},
["track-outline"] = {
type = "outline",
layer = "BORDER",
color = "060606",
},
["grip-background"] = {
type = "texture",
layer = "BACKGROUND",
gradient = "HORIZONTAL",
color = "5d5d5d",
colorEnd = "252525",
},
["grip-outline"] = {
type = "outline",
layer = "BORDER",
color = "060606",
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["scrollFrameContainer-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "fffc00",
},
["scrollFrame-orange"] = {
type = "outline",
layer = "OVERLAY",
color = "ffd400",
},
["scrollingMessageFrame-red"] = {
type = "outline",
layer = "BORDER",
color = "ff0000",
aplha = 0.5,
},
["scrollBar-blue"] = {
type = "outline",
layer = "OVERLAY",
color = "00aaff",
},
["track-green"] = {
type = "outline",
layer = "OVERLAY",
color = "55ff00",
},
}
-- ~~| ScrollingMessageFrame Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class DiesalScrollingMessageFrame : Diesal.GUI.Object.ScrollingMessageFrame
-- ~~| ScrollingMessageFrame Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.ScrollingMessageFrame.Methods
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:SetStylesheet(wireFrame)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
local settings = self.settings
local scrollFrame = self.scrollFrame
scrollFrame:SetPoint("TOPLEFT", settings.contentPadLeft, -settings.contentPadTop)
scrollFrame:SetPoint("BOTTOMRIGHT", -settings.contentPadRight, settings.contentPadBottom)
self.scrollBar:SetWidth(settings.scrollBarWidth)
self.buttonDown:SetHeight(settings.scrollBarButtonHeight)
self.buttonUp:SetHeight(settings.scrollBarButtonHeight)
end,
["ShowScrollBar"] = function(self, show)
if show then
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", -(self.settings.scrollBarWidth + 1), 0)
self.scrollBar:Show()
else
self.scrollBar:Hide()
self.scrollFrameContainer:SetPoint("BOTTOMRIGHT", 0, 0)
end
end,
["SetContentHeight"] = function(self, height)
self.settings.contentHeight = height
self.content:SetHeight(height)
end,
["SetGripSize"] = function(self)
local contentSize = self.scrollFrame:GetVerticalScrollRange() + self.scrollFrame:GetHeight()
local windowSize = self.scrollFrame:GetHeight()
local trackSize = self.track:GetHeight()
local windowContentRatio = windowSize / contentSize
local gripSize = DiesalTools.Round(trackSize * windowContentRatio)
gripSize = max(gripSize, 10) -- might give this a setting?
gripSize = min(gripSize, trackSize)
self.grip:SetHeight(gripSize)
end,
["SetScrollThumbPosition"] = function(self)
local verticalScrollRange = self.scrollFrame:GetVerticalScrollRange() -- windowScrollAreaSize (rounded no need to round)
if verticalScrollRange < 1 then
self.grip:SetPoint("TOP", 0, 0)
return
end
local verticalScroll = self.scrollFrame:GetVerticalScroll() -- windowPosition
local trackSize = self.track:GetHeight()
local gripSize = self.grip:GetHeight()
local windowPositionRatio = verticalScroll / verticalScrollRange
local trackScrollAreaSize = trackSize - gripSize
local gripPositionOnTrack = DiesalTools.Round(trackScrollAreaSize * windowPositionRatio)
self.grip:SetPoint("TOP", 0, -gripPositionOnTrack)
end,
["SetVerticalScroll"] = function(self, scroll) -- user scrolled only
self.settings.forceScrollBottom = DiesalTools.Round(scroll) == DiesalTools.Round(self.scrollFrame:GetVerticalScrollRange())
self.scrollFrame:SetVerticalScroll(scroll)
end,
["AddMessage"] = function(self, msg)
if not msg then
return
end
self.scrollingMessageFrame:AddMessage(msg)
-- ChatFrame1:AddMessage(self.scrollingMessageFrame:GetNumRegions() )
end,
["SetText"] = function(self, txt)
-- self.editBox:SetText(txt or '')
end,
}
-- ~~| ScrollingMessageFrame Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.ScrollingMessageFrame : Diesal.GUI.ObjectBase, Diesal.GUI.ScrollingMessageFrame.Methods
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
scrollBarButtonHeight = 1,
scrollBarWidth = 6,
contentPadLeft = 0,
contentPadRight = 0,
contentPadTop = 0,
contentPadBottom = 0,
forceScrollBottom = true,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHide
-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
local scrollFrameContainer = self:CreateRegion("Frame", "scrollFrameContainer", frame)
scrollFrameContainer:SetAllPoints()
local scrollFrame = self:CreateRegion("ScrollFrame", "scrollFrame", scrollFrameContainer)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", function(this, delta)
DiesalGUI:OnMouse(this, "MouseWheel")
if delta > 0 then
self:SetVerticalScroll(max(this:GetVerticalScroll() - 50, 0))
else
self:SetVerticalScroll(min(this:GetVerticalScroll() + 50, this:GetVerticalScrollRange()))
end
end)
scrollFrame:SetScript("OnVerticalScroll", function(this, offset)
-- self.scrollFrame:GetVerticalScrollRange() windowScrollAreaSize
if this:GetVerticalScrollRange() < 1 then -- nothing to scroll
self:ShowScrollBar(false)
else
self:ShowScrollBar(true)
end
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnScrollRangeChanged", function(this, xOffset, verticalScrollRange)
if verticalScrollRange < 1 then -- nothing to scroll
this:SetVerticalScroll(0)
self:ShowScrollBar(false)
return
end
if self.settings.forceScrollBottom then
this:SetVerticalScroll(verticalScrollRange)
else
this:SetVerticalScroll(min(this:GetVerticalScroll(), verticalScrollRange))
end
self:ShowScrollBar(true)
self:SetGripSize()
self:SetScrollThumbPosition()
end)
scrollFrame:SetScript("OnSizeChanged", function(this, width, height)
self.scrollingMessageFrame:SetWidth(width)
end)
local scrollingMessageFrame = self:CreateRegion("ScrollingMessageFrame", "scrollingMessageFrame", scrollFrame)
scrollingMessageFrame:SetPoint("TOPLEFT")
scrollingMessageFrame:SetPoint("TOPRIGHT")
scrollingMessageFrame:SetJustifyH("LEFT")
scrollingMessageFrame:SetJustifyV("TOP")
scrollingMessageFrame:SetInsertMode("BOTTOM")
scrollingMessageFrame:SetMaxLines(500)
scrollingMessageFrame:SetHeight(500)
scrollingMessageFrame:SetFading(false)
scrollFrame:SetScrollChild(scrollingMessageFrame)
local scrollBar = self:CreateRegion("Frame", "scrollBar", frame)
scrollBar:SetPoint("TOPRIGHT")
scrollBar:SetPoint("BOTTOMRIGHT")
scrollBar:Hide()
local buttonUp = self:CreateRegion("Frame", "buttonUp", scrollBar)
buttonUp:SetPoint("TOPLEFT")
buttonUp:SetPoint("TOPRIGHT")
local buttonDown = self:CreateRegion("Frame", "buttonDown", scrollBar)
buttonDown:SetPoint("BOTTOMLEFT")
buttonDown:SetPoint("BOTTOMRIGHT")
local track = self:CreateRegion("Frame", "track", scrollBar)
track:SetPoint("LEFT")
track:SetPoint("RIGHT")
track:SetPoint("TOP", buttonUp, "BOTTOM", 0, 0)
track:SetPoint("BOTTOM", buttonDown, "TOP", 0, 0)
local grip = self:CreateRegion("Frame", "grip", track)
grip:SetPoint("LEFT")
grip:SetPoint("RIGHT")
grip:SetPoint("TOP")
grip:EnableMouse(true)
grip:SetScript("OnMouseDown", function(this, button)
DiesalGUI:OnMouse(this, button)
if button ~= "LeftButton" then
return
end
local MouseY = select(2, GetCursorPosition()) / this:GetEffectiveScale()
local effectiveScale = this:GetEffectiveScale()
local trackScrollAreaSize = track:GetHeight() - this:GetHeight()
local gripPositionOnTrack = abs(select(5, this:GetPoint(1)))
this:SetScript("OnUpdate", function(this)
local newGripPosition = gripPositionOnTrack + (MouseY - (select(2, GetCursorPosition()) / effectiveScale))
newGripPosition = min(max(newGripPosition, 0), trackScrollAreaSize)
-- local newGripPositionRatio = newGripPosition / trackScrollAreaSize
-- local windowPosition = newGripPositionRatio * scrollArea:GetVerticalScrollRange()
self:SetVerticalScroll((newGripPosition / trackScrollAreaSize) * scrollFrame:GetVerticalScrollRange())
end)
end)
grip:SetScript("OnMouseUp", function(this, button)
this:SetScript("OnUpdate", function(this) end)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,345 @@
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
local round = DiesalTools.Round
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Spinner |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalSpinner"
local Version = 3
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.6,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.6,
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.02,
position = 1,
},
["frame-hover"] = {
type = "outline",
layer = "HIGHLIGHT",
color = "FFFFFF",
alpha = 0.25,
position = -1,
},
["editBox-font"] = {
type = "Font",
color = Colors.UI_TEXT,
},
["bar-background"] = {
type = "texture",
layer = "BACKGROUND",
gradient = { "VERTICAL", Colors.UI_A100, ShadeColor(Colors.UI_A100, 0.1) },
},
["bar-inline"] = {
type = "outline",
layer = "BORDER",
gradient = { "VERTICAL", "FFFFFF", "FFFFFF" },
alpha = { 0.07, 0.02 },
},
["bar-outline"] = {
type = "texture",
layer = "ARTWORK",
color = "000000",
alpha = 0.7,
width = 1,
position = { nil, 1, 0, 0 },
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["editBox-purple"] = {
type = "outline",
layer = "OVERLAY",
color = "aa00ff",
},
["buttonUp-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "fffc00",
},
["buttonDown-orange"] = {
type = "outline",
layer = "OVERLAY",
color = "ffd400",
},
["bar-green"] = {
type = "outline",
layer = "OVERLAY",
color = "55ff00",
},
}
-- | Internal Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function processNumber(self, number)
local settings = self.settings
local number, oldNumber = tonumber(number), self:GetNumber()
if not number then
number = oldNumber or settings.min
else
number = max(min(number, settings.max), settings.min)
end
settings.number = number
self.editBox:SetText((settings.prefix or "") .. number .. (settings.suffix or ""))
self.editBox:HighlightText(0, 0) -- clear any selcted text
self.editBox:SetCursorPosition(0)
self:UpdateBar()
if number ~= oldNumber then
return number
end
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Spinner.Methods
local methods = {
---@param self Diesal.GUI.Object.Spinner
OnAcquire = function(self)
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:ApplySettings()
self:Show()
end,
---@param self Diesal.GUI.Object.Spinner
OnRelease = function(self) end,
---@param self Diesal.GUI.Object.Spinner
ApplySettings = function(self)
local settings = self.settings
local frame = self.frame
local buttonUp = self.buttonUp
local buttonDown = self.buttonDown
local editBox = self.editBox
local buttonsWidth = settings.buttons and settings.buttonsWidth or 0
local buttonHeight = round(settings.height / 2)
-- Apply Settings
self:SetWidth(settings.width)
self:SetHeight(settings.height)
editBox:EnableMouse(settings.mouse)
editBox:EnableMouseWheel(settings.mouseWheel)
editBox:SetPoint("BOTTOMRIGHT", -buttonsWidth, 0)
buttonUp[settings.buttons and "Show" or "Hide"](buttonUp)
buttonUp:EnableMouse(settings.mouse)
buttonUp:SetHeight(buttonHeight)
buttonUp:SetWidth(buttonsWidth)
buttonDown[settings.buttons and "Show" or "Hide"](buttonDown)
buttonDown:EnableMouse(settings.mouse)
buttonDown:SetHeight(buttonHeight)
buttonDown:SetWidth(buttonsWidth)
self:UpdateBar()
end,
---@param self Diesal.GUI.Object.Spinner
EnableMouse = function(self, enable)
self.settings.mouse = enable
self.buttonUp:EnableMouse(enable)
self.buttonDown:EnableMouse(enable)
self.editBox:EnableMouse(enable)
self.editBox:EnableMouseWheel(enable)
end,
---@param self Diesal.GUI.Object.Spinner
GetNumber = function(self)
return self.settings.number
end,
---@param self Diesal.GUI.Object.Spinner
SetNumber = function(self, number)
local newNumber = processNumber(self, number)
if newNumber then
self:FireEvent("OnValueChanged", false, newNumber)
end
end,
---@param self Diesal.GUI.Object.Spinner
SetPrefix = function(self, prefix)
self.settings.prefix = prefix
processNumber(self, self.settings.number)
end,
---@param self Diesal.GUI.Object.Spinner
SetSuffix = function(self, suffix)
self.settings.suffix = suffix
processNumber(self, self.settings.number)
end,
---@param self Diesal.GUI.Object.Spinner
OnSpin = function(self, delta)
local step = IsShiftKeyDown() and self.settings.shiftStep or self.settings.step
local oldNumber = self.settings.number
local newNumber
if delta > 0 then
newNumber = processNumber(self, round(oldNumber, step) + step)
else
newNumber = processNumber(self, round(oldNumber, step) - step)
end
if newNumber then
self:FireEvent("OnValueChanged", true, newNumber)
end
end,
---@param self Diesal.GUI.Object.Spinner
UpdateBar = function(self)
if not self.settings.bar then
return
end
local settings = self.settings
local barWidth = self:GetWidth() - (settings.buttons and settings.buttonsWidth or 0) - 2 -- bar padding
local number = settings.number or settings.min
local width = round(((number - settings.min) / (settings.max - settings.min) * barWidth))
if width == 0 then
self.bar:Hide()
else
self.bar:Show()
self.bar:SetWidth(width)
end
self.value = settings.number
end,
---@param self Diesal.GUI.Object.Spinner
SetTextColor = function(self, color, alpha)
alpha = alpha or 1
color = { DiesalTools.GetColor(color) }
self.editBox:SetTextColor(color[1], color[2], color[3], alpha)
end,
}
---@class DiesalSpinner : Diesal.GUI.Object.Spinner
---@class Diesal.GUI.Object.Spinner.Settings.Defaults
---@field height number
---@field width number
---@field mouse boolean
---@field mouseWheel boolean
---@field buttons boolean
---@field buttonsWidth number
---@field bar boolean
---@field min number
---@field max number
---@field step number
---@field shiftStep number
---@class Diesal.GUI.Object.Spinner.Settings: Diesal.GUI.Object.Spinner.Settings.Defaults
---@field number number
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Spinner : Diesal.GUI.ObjectBase, Diesal.GUI.Spinner.Methods
---@field settings Diesal.GUI.Object.Spinner.Settings
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 16,
width = 29,
mouse = true,
mouseWheel = true,
buttons = false,
buttonsWidth = 8,
bar = true,
min = 0,
max = 100,
step = 5,
shiftStep = 1,
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnHide", function(this)
self:FireEvent("OnHide")
end)
frame:SetScript("OnSizeChanged", function()
self:UpdateBar()
end)
local editBox = self:CreateRegion("EditBox", "editBox", frame) --[[ @asDiesal.GUI.Region.EditBoxx ]]
editBox:SetPoint("TOP")
editBox:SetPoint("BOTTOM")
editBox:SetAutoFocus(false)
editBox:SetJustifyH("CENTER")
editBox:SetJustifyV("CENTER")
editBox:SetTextInsets(0, 0, 0, 0)
editBox:SetText(self.defaults.min)
editBox:SetScript("OnEnterPressed", function(this, ...)
local number = this:GetNumber() or self.settings.number -- if entered text or nothing revert to old value
local newNumber = processNumber(self, number)
if newNumber then
self:FireEvent("OnValueChanged", true, newNumber)
end
self:FireEvent("OnEnterPressed", ...)
DiesalGUI:ClearFocus()
end)
editBox:HookScript("OnEditFocusLost", function(this, ...)
processNumber(self, self.settings.number)
end)
editBox:HookScript("OnEditFocusGained", function(this)
this:SetText(self.settings.number)
this:HighlightText()
end)
editBox:SetScript("OnMouseWheel", function(this, delta)
DiesalGUI:OnMouse(this, "MouseWheel")
self:OnSpin(delta)
end)
editBox:SetScript("OnEnter", function(this, ...)
self:FireEvent("OnEnter", ...)
end)
editBox:SetScript("OnLeave", function(this, ...)
self:FireEvent("OnLeave", ...)
end)
local bar = self:CreateRegion("Frame", "bar", frame)
bar:SetPoint("TOPLEFT", 1, -1)
bar:SetPoint("BOTTOMLEFT", -1, 1)
local buttonUp = self:CreateRegion("Button", "buttonUp", frame)
buttonUp:SetPoint("TOP", 0, 0)
buttonUp:SetPoint("RIGHT")
buttonUp:SetScript("OnClick", function(this, button)
DiesalGUI:OnMouse(this, button)
PlaySound(799)
self:OnSpin(1)
end)
local buttonDown = self:CreateRegion("Button", "buttonDown", frame)
buttonDown:SetPoint("BOTTOM", 0, 0)
buttonDown:SetPoint("RIGHT")
buttonDown:SetScript("OnClick", function(this, button)
DiesalGUI:OnMouse(this, button)
PlaySound(799)
self:OnSpin(-1)
end)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,43 @@
---@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 = "DiesalText"
local Version = 1
---@class Diesal.GUI.Text.Methods : Diesal.GUI.ObjectBase
---@field OnAcquire fun(self:Diesal.GUI.Object.Text, ...)
---@field OnRelease fun(self:Diesal.GUI.Object.Text, ...)
local methods = {
OnAcquire = function(self, ...)
self:Show()
end,
OnRelease = function(self, ...)
--self.fontString:SetText("")
end,
}
---@class DiesalText : Diesal.GUI.Object.Text
local function Constructor()
---@class Diesal.GUI.Object.Text : Diesal.GUI.ObjectBase, Diesal.GUI.Text.Methods, Frame
---@field fontString FontString
local self = DiesalGUI:Create(Type, true)
self.defaults = {}
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
self:CreateRegion("FontString", "fontString", frame)
--local fontString = frame:CreateFontString(nil, "OVERLAY", "DiesalFontNormal")
--self.fontString = fontString
self.fontStrings[#self.fontStrings + 1] = self.fontString
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,245 @@
---@type Tinkr, Bastion
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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, tonumber, select = type, tonumber, select
local pairs, ipairs, next = pairs, ipairs, next
local min, max = math.min, math.max
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
-- ~~| Button |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalToggle"
local Version = 1
-- ~~| Button Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.60,
position = -2,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "000000",
alpha = 0.6,
position = -2,
},
["frame-outline"] = {
type = "outline",
layer = "BORDER",
color = "FFFFFF",
alpha = 0.1,
position = -1,
},
}
local checkBoxStyle = {
base = {
type = "texture",
layer = "ARTWORK",
color = Colors.UI_A400,
position = -3,
},
disabled = {
type = "texture",
color = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.35),
},
enabled = {
type = "texture",
color = Colors.UI_A400,
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
}
-- ~~| Button Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Toggle.Methods
local methods = {
---@param self DiesalToggle
OnAcquire = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
self:Enable()
-- self:SetStylesheet(wireFrameSheet)
self.label:SetFontObject(DiesalFontNormal)
self.label:SetText()
self:Show()
end,
---@param self DiesalToggle
OnRelease = function(self) end,
---@param self DiesalToggle
ApplySettings = function(self)
local settings = self.settings
local frame = self.frame
self:SetWidth(settings.width)
self:SetHeight(settings.height)
end,
---@param self DiesalToggle
---@param value boolean
SetChecked = function(self, value)
self.settings.checked = value
self.frame:SetChecked(value)
self[self.settings.disabled and "Disable" or "Enable"](self)
end,
---@param self DiesalToggle
GetChecked = function(self)
return self.settings.checked
end,
---@param self DiesalToggle
Disable = function(self)
self.settings.disabled = true
DiesalStyle:StyleTexture(self.check, self.checkBoxStyle and self.checkBoxStyle.disabled or checkBoxStyle.disabled)
self.frame:Disable()
end,
---@param self DiesalToggle
Enable = function(self)
self.settings.disabled = false
DiesalStyle:StyleTexture(self.check, self.checkBoxStyle and self.checkBoxStyle.enabled or checkBoxStyle.enabled)
self.frame:Enable()
end,
---@param self DiesalToggle
---@param ... any
RegisterForClicks = function(self, ...)
self.frame:RegisterForClicks(...)
end,
---@param self DiesalToggle
---@param text? string
SetText = function(self, text)
self.label:SetText(text)
self.frame:SetHitRectInsets(0, -self.label:GetWidth(), 0, 0)
end,
}
---@alias DiesalToggle Diesal.GUI.Object.Toggle
---@class Diesal.Style.CheckBox.Style
---@field base {type: "texture", layer: "ARTWORK", color: string, position: number}
---@field disabled {type: "texture", color: string}
---@field enabled {type: "texture", color: string}}
---@class Diesal.GUI.Toggle.Settings
---@field height number
---@field width number
---@field checked boolean
---@field disabled boolean
---@field tooltip? string
-- ~~| Button Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Toggle : Diesal.GUI.ObjectBase, Diesal.GUI.Toggle.Methods
---@field check Texture
---@field settings Diesal.GUI.Toggle.Settings
---@field checkBoxStyle? Diesal.Style.CheckBox.Style
---@field label FontString
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("CheckButton", nil, UIParent)
local fontString = self:CreateRegion("FontString", "label", frame)
self.frame = frame
local c, a = 0.5, 0.5
local tex = frame:CreateTexture(nil, "BACKGROUND")
tex:SetAllPoints()
tex:SetColorTexture(0, 0, 0, 0)
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
height = 12,
width = 12,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnValueChanged, OnEnter, OnLeave, OnDisable, OnEnable
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local check = self:CreateRegion("Texture", "check", frame)
-- Setting self.check again is pointless when CreateRegion already does it....
-- self.check = check
DiesalStyle:StyleTexture(check, self.checkBoxStyle and self.checkBoxStyle.base or checkBoxStyle.base)
frame:SetCheckedTexture(check)
frame:SetScript("OnClick", function(this, button, ...)
DiesalGUI:OnMouse(this, button)
if not self.settings.disabled then
self:SetChecked(not self.settings.checked)
if self.settings.checked then
PlaySound(856)
else
PlaySound(857)
end
self:FireEvent("OnValueChanged", self.settings.checked)
end
end)
frame:SetScript("OnEnter", function(this)
if self.settings.tooltip then
GameTooltip:SetOwner(this, "ANCHOR_TOPLEFT", 0, 2)
GameTooltip:AddLine(self.settings.tooltip)
GameTooltip:Show()
end
self:FireEvent("OnEnter")
tex:SetColorTexture(c, c, c, a)
-- SetCursor([[Interface\Cursor\Cast]])
end)
frame:SetScript("OnLeave", function(this)
if self.settings.tooltip then
GameTooltip:Hide()
end
self:FireEvent("OnLeave")
tex:SetColorTexture(0, 0, 0, 0)
-- SetCursor(nil)
end)
frame:SetScript("OnDisable", function(this)
self:FireEvent("OnDisable")
end)
frame:SetScript("OnEnable", function(this)
self:FireEvent("OnEnable")
end)
fontString:SetPoint("LEFT", frame, "RIGHT", 5, 0)
fontString:SetHeight(0)
fontString:SetJustifyH("MIDDLE")
fontString:SetJustifyV("MIDDLE")
fontString:SetWordWrap(false)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,104 @@
---@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
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Tree |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalTree"
local Version = 4
---@class DTree : Diesal.GUI.Object.Tree
-- ~~| Tree Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["content-background"] = {
type = "texture",
color = "ffffff",
alpha = 0.01,
},
}
-- ~~| Tree Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function collapse(branch)
if branch.Collapse then
branch:Collapse()
end
if branch.children and next(branch.children) then
for i = 1, #branch.children do
collapse(branch.children[i])
end
end
end
-- ~~| Tree Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Tree.Methods
local methods = {
["OnAcquire"] = function(self)
-- self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrameSheet)
self:ApplySettings()
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self) end,
["UpdateHeight"] = function(self)
local height = 0
for i = 1, #self.children do
height = height + self.children[i].frame:GetHeight()
end
height = DiesalTools.Round(height)
if self.settings.height ~= height then
self.settings.height = height
self:SetHeight(height)
self:FireEvent("OnHeightChange", height)
end
end,
["CollapseAll"] = function(self, subBranches)
if subBranches then
collapse(self)
else
for i = 1, #self.children do
self.children[i]:Collapse()
end
end
end,
["ExpandAll"] = function(self)
for i = 1, #self.children do
self.children[i]:Expand()
end
end,
}
---@class DiesalTree : Diesal.GUI.Object.Tree
-- ~~| Tree Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.GUI.Object.Tree : Diesal.GUI.ObjectBase, Diesal.GUI.Tree.Methods
local self = DiesalGUI:Create(Type, true)
self.isContainer = true
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = { depth = 0 }
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- OnHeightChange
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local content = self:CreateRegion("Frame", "content", frame)
content:SetAllPoints()
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self:SetMethods(methods)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,462 @@
---@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",
},
["titleBar-color"] = {
type = "texture",
layer = "BACKGROUND",
color = "000000",
alpha = 0.95,
},
["titletext-Font"] = {
type = "font",
color = "d8d8d8",
},
["closeButton-icon"] = {
type = "texture",
layer = "ARTWORK",
image = { "DiesalGUIcons", { 9, 5, 16, 256, 128 } },
alpha = 0.3,
position = { -2, nil, -1, nil },
width = 16,
height = 16,
},
["closeButton-iconHover"] = {
type = "texture",
layer = "HIGHLIGHT",
image = { "DiesalGUIcons", { 9, 5, 16, 256, 128 }, "b30000" },
alpha = 1,
position = { -2, nil, -1, nil },
width = 16,
height = 16,
},
["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)
closeButton:SetWidth(settings.titleBarHeight)
content:SetPoint("TOPLEFT", settings.padding[1], -(settings.titleBarHeight + headerHeight))
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,
}
---@class Diesal.GUI.Window.Frame : Frame, { obj: Diesal.GUI.Object.Window }
---@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]: number, [2]: number, [3]: number, [4]: number }
---@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 Diesal.GUI.Window.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
---@type Diesal.GUI.Window.Frame
local frame = CreateFrame("Frame", nil, UIParent)
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)
frame.obj = self
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:SetPoint("TOPRIGHT", -1, 1)
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("TOPLEFT", 4, -5)
titletext:SetPoint("TOPRIGHT", -20, -5)
titletext:SetJustifyH("TOP")
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)
--[[ for method, func in pairs(methods) do
self[method] = func
end ]]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -1,69 +0,0 @@
-- $Id: DiesalMenu-1.0.lua 53 2016-07-12 21:56:30Z diesal2010 $
local MAJOR, MINOR = "DiesalMenu-1.0", "$Rev: 53 $"
local DiesalMenu, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalMenu then return end -- No Upgrade needed.
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub("DiesalTools-1.0")
local DiesalStyle = LibStub("DiesalStyle-1.0")
local DiesalGUI = LibStub("DiesalGUI-1.0")
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, tonumber = type, select, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper, match = string.sub, string.format, string.lower, string.upper, string.match
local pairs, ipairs = pairs,ipairs
local tinsert, tremove, tconcat, tsort = table.insert, table.remove, table.concat, table.sort
local floor, ceil, abs, modf = math.floor, math.ceil, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent = CreateFrame, UIParent
-- ~~| DiesalMenu Values |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| DiesalMenu Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| DiesalStyle Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local MENU
local CLOSEDELAY = 2
local closeTimer = CreateFrame('Frame')
closeTimer:Hide()
closeTimer:SetScript('OnUpdate', function(this,elapsed)
if this.count < 0 then
DiesalMenu:Close()
this:Hide()
else
this.count = this.count - elapsed
end
end)
-- ~~| DiesalMenu Local Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| DiesalMenu API |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DiesalMenu:Menu(menuData,anchor,x,y,closeDelay)
MENU = MENU or DiesalGUI:Create('Menu')
MENU:ResetSettings()
if not MENU:BuildMenu(menuData) then MENU:Hide() return end
MENU:Show()
MENU:ClearAllPoints()
MENU:SetPoint('TOPLEFT',anchor,'TOPLEFT',x,y)
closeTimer.closeDelay = closeDelay or CLOSEDELAY
DiesalMenu:StartCloseTimer()
DiesalMenu:SetFocus()
end
function DiesalMenu:Close()
DiesalMenu:StopCloseTimer()
if not MENU or not MENU:IsVisible() then return end
MENU:ResetSettings()
MENU:ReleaseChildren()
MENU:Hide()
MENU:ClearAllPoints()
end
function DiesalMenu:StartCloseTimer()
closeTimer.count = closeTimer.closeDelay
closeTimer:Show()
end
function DiesalMenu:StopCloseTimer()
closeTimer:Hide()
end
function DiesalMenu:ClearFocus()
DiesalMenu:Close()
end
function DiesalMenu:SetFocus()
DiesalGUI:SetFocus(DiesalMenu)
end

@ -1,6 +0,0 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Script file="DiesalMenu-1.0.lua"/>
<!-- Objects -->
<Script file="Objects\Menu.lua"/>
<Script file="Objects\MenuItem.lua"/>
</Ui>

@ -1,132 +0,0 @@
-- $Id: Menu.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalMenu = LibStub('DiesalMenu-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalGUI = LibStub('DiesalGUI-1.0')
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local ipairs, pairs, table_sort = ipairs, pairs, table.sort
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Menu |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'Menu'
local Version = 2
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-background'] = {
type = 'texture',
layer = 'BACKGROUND',
color = Colors.UI_100,
alpha = .95,
},
['frame-inline'] = {
type = 'outline',
layer = 'BORDER',
color = 'ffffff',
alpha = .02,
position = -1,
},
['frame-shadow'] = {
type = 'shadow',
},
}
local wireFrame = {
['frame-white'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'ffffff',
},
['content-yellow'] = {
type = 'outline',
layer = 'OVERLAY',
color = 'fffc00',
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a,b)
return a[1] < b[1]
end
local function sortTable(t)
local st = {}
for key, val in pairs(t) do
st[#st + 1] = {val.order, key}
end
table_sort(st,compare)
return st
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
self:UpdatePosition()
end,
['UpdatePosition'] = function(self)
self.content:SetPoint("TOPLEFT",self.settings.padding[1],-self.settings.padding[3])
self.content:SetPoint("BOTTOMRIGHT",-self.settings.padding[2],self.settings.padding[4])
end,
['UpdateSize'] = function(self)
local menuHeight = 0
for i=1, #self.children do
menuHeight = menuHeight + self.children[i].frame:GetHeight()
end
self.frame:SetHeight(self.settings.padding[3] + menuHeight + self.settings.padding[4])
self.frame:SetWidth(self.settings.padding[1] + self.settings.itemWidth + self.settings.padding[2])
end,
['BuildMenu'] = function(self, menuData)
if menuData then self.settings.menuData = menuData else menuData = self.settings.menuData end
if not menuData then return end
-- reset menu
self:ReleaseChildren()
self:SetWidth(1)
-- set menu properties
for key in pairs(menuData) do
if menuData[key].check then self.settings.check = true end
if menuData[key].menuData then self.settings.arrow = true end
end
-- create menuItems
local sortedTable = sortTable(menuData)
for i = 1, #sortedTable do
local menuItem = DiesalGUI:Create('MenuItem')
self:AddChild(menuItem)
menuItem:SetParentObject(self)
menuItem:SetSettings({
itemData = menuData[sortedTable[i][2]],
position = i,
},true)
end
self:UpdateSize()
return true
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Frame',nil,UIParent)
self.frame = frame
self.defaults = {
itemWidth = 0,
padding = {4,4,8,8},
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetClampedToScreen( true )
frame:SetScript('OnEnter', function(this) DiesalMenu:StopCloseTimer() end)
frame:SetScript('OnLeave', function(this) DiesalMenu:StartCloseTimer() end)
self:CreateRegion("Frame", 'content', frame)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -1,157 +0,0 @@
-- $Id: MenuItem.lua 60 2016-11-04 01:34:23Z diesal2010 $
local DiesalMenu = LibStub('DiesalMenu-1.0')
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalTools = LibStub('DiesalTools-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
local DiesalGUI = LibStub('DiesalGUI-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | MenuItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = 'MenuItem'
local Version = 2
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
['frame-hover'] = {
type = 'texture',
layer = 'HIGHLIGHT',
color = Colors.UI_1000,
alpha = .1,
},
['text-color'] = {
type = 'Font',
color = 'cbcbcb',
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
['OnAcquire'] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:Show()
end,
['OnRelease'] = function(self)
end,
['ApplySettings'] = function(self)
if not self.settings.itemData then return false end
local settings = self.settings
local menuSettings= settings.parentObject.settings
local itemData = settings.itemData
local text = self.text
local check = self.check
local arrow = self.arrow
local checkWidth = menuSettings.check and settings.checkWidth or settings.textPadLeft
local arrowWidth = menuSettings.arrow and settings.arrowWidth or settings.textPadRight
local textWidthMax = settings.widthMax - arrowWidth - checkWidth
if settings.position == 1 then
self:SetPoint('TOPLEFT')
self:SetPoint('RIGHT')
else
self:SetPoint('TOPLEFT',settings.parentObject.children[settings.position-1].frame,'BOTTOMLEFT',0,0)
self:SetPoint('RIGHT')
end
if itemData.type == 'spacer' then
self.frame:EnableMouse(false)
self:SetHeight(settings.spacerHeight)
else
self.frame:EnableMouse(true)
self:SetHeight(settings.height)
end
self:SetText(itemData.name)
text:SetPoint("LEFT",checkWidth, 0)
text:SetPoint("RIGHT",-arrowWidth, 0)
arrow[menuSettings.arrow and itemData.menuData and "Show" or "Hide"](arrow)
check[menuSettings.check and itemData.check and itemData.check() and "Show" or "Hide"](check)
local textWidth = DiesalTools.Round(text:GetStringWidth()) + 10
local itemWidth = checkWidth + textWidth + arrowWidth
menuSettings.itemWidth = min(max(menuSettings.itemWidth,itemWidth),settings.widthMax)
end,
['SetText'] = function(self,text)
self.text:SetText(text or '')
end,
['OnClick'] = function(self)
local onClick = self.settings.itemData.onClick
if onClick then onClick() end
end,
['OnEnter'] = function(self)
DiesalMenu:StopCloseTimer()
local menuChildren = self.settings.parentObject.children
local menuData = self.settings.itemData.menuData
for i=1, #menuChildren do menuChildren[i]:ReleaseChildren() end
self:BuildSubMenu(menuData)
end,
['BuildSubMenu'] = function(self,menuData)
if not menuData then return end
local subMenu = DiesalGUI:Create('Menu')
if not subMenu:BuildMenu(menuData) then DiesalGUI:Release(subMenu) return end
self:AddChild(subMenu)
subMenu:SetParent(self.frame)
subMenu:ClearAllPoints()
subMenu:SetPoint('TOPLEFT',self.frame,'TOPRIGHT',0,0)
subMenu:Show()
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
local self = DiesalGUI:CreateObjectBase(Type)
local frame = CreateFrame('Button',nil,UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
widthMax = 250,
height = 16,
spacerHeight = 5,
checkWidth = 14,
arrowWidth = 14,
textPadLeft = 2,
textPadRight = 2,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnClick", function(this,button) DiesalGUI:OnMouse(this,button); self:OnClick() end)
frame:SetScript('OnEnter', function(this) self:OnEnter() end)
frame:SetScript('OnLeave', function(this) DiesalMenu:StartCloseTimer() end)
local text = self:CreateRegion("FontString", 'text', frame)
text:SetPoint("TOP",0,-2)
text:SetPoint("BOTTOM",0,0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", 'check', frame)
DiesalStyle:StyleTexture(check,{
position = {1,nil,0,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons', {10,5,16,256,128},'FFFF00'},
})
local arrow = self:CreateRegion("Texture", 'arrow', frame)
DiesalStyle:StyleTexture(arrow,{
position = {nil,2,-1,nil},
height = 16,
width = 16,
image = {'DiesalGUIcons', {7,5,16,256,128},'FFFF00'},
})
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do self[method] = func end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)

@ -0,0 +1,93 @@
local MAJOR, MINOR = "DiesalMenu-2.0", 1
---@alias Diesal.Menu DiesalMenu-2.0
---@class DiesalMenu-2.0
local DiesalMenu = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalMenu then
return
end -- No Upgrade needed.
---@type Diesal.Tools
local DiesalTools = LibStub("DiesalTools-2.0")
---@type Diesal.Style
local DiesalStyle = LibStub("DiesalStyle-2.0")
---@type Diesal.GUI
local DiesalGUI = LibStub("DiesalGUI-2.0")
local type, select, tonumber = type, select, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper, match = string.sub, string.format, string.lower, string.upper, string.match
local pairs, ipairs = pairs, ipairs
local tinsert, tremove, tconcat, tsort = table.insert, table.remove, table.concat, table.sort
local floor, ceil, abs, modf = math.floor, math.ceil, math.abs, math.modf
local CreateFrame, UIParent = CreateFrame, UIParent
---@type Diesal.Menu.Menu
local MENU
local CLOSEDELAY = 2
---@class Diesal.Menu.CloseTimer : Frame
---@field closeDelay number
local closeTimer = CreateFrame("Frame")
closeTimer:Hide()
---@param this Diesal.Menu.CloseTimer
---@param elapsed number
closeTimer:SetScript("OnUpdate", function(this, elapsed)
if this.count < 0 then
DiesalMenu:Close()
this:Hide()
else
this.count = this.count - elapsed
end
end)
---@param menuData any
---@param anchor any
---@param x number
---@param y number
---@param closeDelay number
function DiesalMenu:Menu(menuData, anchor, x, y, closeDelay)
MENU = MENU or DiesalGUI:Create("DiesalMenu")
MENU:ResetSettings()
if not MENU:BuildMenu(menuData) then
MENU:Hide()
return
end
MENU:Show()
MENU:ClearAllPoints()
MENU:SetPoint("TOPLEFT", anchor, "TOPLEFT", x, y)
closeTimer.closeDelay = closeDelay or CLOSEDELAY
DiesalMenu:StartCloseTimer()
DiesalMenu:SetFocus()
end
function DiesalMenu:Close()
DiesalMenu:StopCloseTimer()
if not MENU or not MENU:IsVisible() then
return
end
MENU:ResetSettings()
MENU:ReleaseChildren()
MENU:Hide()
MENU:ClearAllPoints()
end
function DiesalMenu:StartCloseTimer()
closeTimer.count = closeTimer.closeDelay
closeTimer:Show()
end
function DiesalMenu:StopCloseTimer()
closeTimer:Hide()
end
function DiesalMenu:ClearFocus()
DiesalMenu:Close()
end
function DiesalMenu:SetFocus()
DiesalGUI:SetFocus(DiesalMenu)
end

@ -0,0 +1,7 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Script file="DiesalMenu-2.0.lua" />
<!-- Objects -->
<Script file="Objects\Menu.lua" />
<Script file="Objects\MenuItem.lua" />
</Ui>

@ -0,0 +1,151 @@
---@type Diesal.Menu
local DiesalMenu = LibStub("DiesalMenu-2.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@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")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local ipairs, pairs, table_sort = ipairs, pairs, table.sort
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Menu |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalMenu"
local Version = 2
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-background"] = {
type = "texture",
layer = "BACKGROUND",
color = Colors.UI_100,
alpha = 0.95,
},
["frame-inline"] = {
type = "outline",
layer = "BORDER",
color = "ffffff",
alpha = 0.02,
position = -1,
},
["frame-shadow"] = {
type = "shadow",
},
}
local wireFrame = {
["frame-white"] = {
type = "outline",
layer = "OVERLAY",
color = "ffffff",
},
["content-yellow"] = {
type = "outline",
layer = "OVERLAY",
color = "fffc00",
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function compare(a, b)
return a[1] < b[1]
end
local function sortTable(t)
local st = {}
for key, val in pairs(t) do
st[#st + 1] = { val.order, key }
end
table_sort(st, compare)
return st
end
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.Menu.Menu.Methods
local methods = {
["OnAcquire"] = function(self)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
self:UpdatePosition()
end,
["UpdatePosition"] = function(self)
self.content:SetPoint("TOPLEFT", self.settings.padding[1], -self.settings.padding[3])
self.content:SetPoint("BOTTOMRIGHT", -self.settings.padding[2], self.settings.padding[4])
end,
["UpdateSize"] = function(self)
local menuHeight = 0
for i = 1, #self.children do
menuHeight = menuHeight + self.children[i].frame:GetHeight()
end
self.frame:SetHeight(self.settings.padding[3] + menuHeight + self.settings.padding[4])
self.frame:SetWidth(self.settings.padding[1] + self.settings.itemWidth + self.settings.padding[2])
end,
["BuildMenu"] = function(self, menuData)
if menuData then
self.settings.menuData = menuData
else
menuData = self.settings.menuData
end
if not menuData then
return
end
-- reset menu
self:ReleaseChildren()
self:SetWidth(1)
-- set menu properties
for key in pairs(menuData) do
if menuData[key].check then
self.settings.check = true
end
if menuData[key].menuData then
self.settings.arrow = true
end
end
-- create menuItems
local sortedTable = sortTable(menuData)
for i = 1, #sortedTable do
local menuItem = DiesalGUI:Create("DiesalMenuItem")
self:AddChild(menuItem)
menuItem:SetParentObject(self)
menuItem:SetSettings({
itemData = menuData[sortedTable[i][2]],
position = i,
}, true)
end
self:UpdateSize()
return true
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.Menu.Menu : Diesal.GUI.ObjectBase, Diesal.Menu.Menu.Methods
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame
self.defaults = {
itemWidth = 0,
padding = { 4, 4, 8, 8 },
}
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetClampedToScreen(true)
frame:SetScript("OnEnter", function(this)
DiesalMenu:StopCloseTimer()
end)
frame:SetScript("OnLeave", function(this)
DiesalMenu:StartCloseTimer()
end)
self:CreateRegion("Frame", "content", frame)
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do
self[method] = func
end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

@ -0,0 +1,184 @@
---@type Diesal.Menu
local DiesalMenu = LibStub("DiesalMenu-2.0")
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@type Diesal.Tools
local DiesalTools = LibStub("DiesalTools-2.0")
---@type Diesal.Style
local DiesalStyle = LibStub("DiesalStyle-2.0")
---@type Diesal.GUI
local DiesalGUI = LibStub("DiesalGUI-2.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | MenuItem |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalMenuItem"
local Version = 2
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
["frame-hover"] = {
type = "texture",
layer = "HIGHLIGHT",
color = Colors.UI_1000,
alpha = 0.1,
},
["text-color"] = {
type = "Font",
color = "cbcbcb",
},
}
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.Menu.MenuItem
local methods = {
["OnAcquire"] = function(self)
self:ApplySettings()
self:SetStylesheet(Stylesheet)
-- self:SetStylesheet(wireFrame)
self:Show()
end,
["OnRelease"] = function(self) end,
["ApplySettings"] = function(self)
if not self.settings.itemData then
return false
end
local settings = self.settings
local menuSettings = settings.parentObject.settings
local itemData = settings.itemData
local text = self.text
local check = self.check
local arrow = self.arrow
local checkWidth = menuSettings.check and settings.checkWidth or settings.textPadLeft
local arrowWidth = menuSettings.arrow and settings.arrowWidth or settings.textPadRight
local textWidthMax = settings.widthMax - arrowWidth - checkWidth
if settings.position == 1 then
self:SetPoint("TOPLEFT")
self:SetPoint("RIGHT")
else
self:SetPoint("TOPLEFT", settings.parentObject.children[settings.position - 1].frame, "BOTTOMLEFT", 0, 0)
self:SetPoint("RIGHT")
end
if itemData.type == "spacer" then
self.frame:EnableMouse(false)
self:SetHeight(settings.spacerHeight)
else
self.frame:EnableMouse(true)
self:SetHeight(settings.height)
end
self:SetText(itemData.name)
text:SetPoint("LEFT", checkWidth, 0)
text:SetPoint("RIGHT", -arrowWidth, 0)
arrow[menuSettings.arrow and itemData.menuData and "Show" or "Hide"](arrow)
check[menuSettings.check and itemData.check and itemData.check() and "Show" or "Hide"](check)
local textWidth = DiesalTools.Round(text:GetStringWidth()) + 10
local itemWidth = checkWidth + textWidth + arrowWidth
menuSettings.itemWidth = min(max(menuSettings.itemWidth, itemWidth), settings.widthMax)
end,
["SetText"] = function(self, text)
self.text:SetText(text or "")
end,
["OnClick"] = function(self)
local onClick = self.settings.itemData.onClick
if onClick then
onClick()
end
end,
["OnEnter"] = function(self)
DiesalMenu:StopCloseTimer()
local menuChildren = self.settings.parentObject.children
local menuData = self.settings.itemData.menuData
for i = 1, #menuChildren do
menuChildren[i]:ReleaseChildren()
end
self:BuildSubMenu(menuData)
end,
["BuildSubMenu"] = function(self, menuData)
if not menuData then
return
end
local subMenu = DiesalGUI:Create("DiesalMenu") --[[ @as Diesal.Menu.Menu ]]
if not subMenu:BuildMenu(menuData) then
DiesalGUI:Release(subMenu)
return
end
self:AddChild(subMenu)
subMenu:SetParent(self.frame)
subMenu:ClearAllPoints()
subMenu:SetPoint("TOPLEFT", self.frame, "TOPRIGHT", 0, 0)
subMenu:Show()
end,
}
-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
---@class Diesal.Menu.MenuItem : Diesal.GUI.ObjectBase
---@field text FontString
---@field check Texture
---@field arrow Texture
local self = DiesalGUI:Create(Type, true)
local frame = CreateFrame("Button", nil, UIParent)
self.frame = frame
-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.defaults = {
widthMax = 250,
height = 16,
spacerHeight = 5,
checkWidth = 14,
arrowWidth = 14,
textPadLeft = 2,
textPadRight = 2,
}
-- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
frame:SetScript("OnClick", function(this, button)
DiesalGUI:OnMouse(this, button)
self:OnClick()
end)
frame:SetScript("OnEnter", function(this)
self:OnEnter()
end)
frame:SetScript("OnLeave", function(this)
DiesalMenu:StartCloseTimer()
end)
local text = self:CreateRegion("FontString", "text", frame)
text:SetPoint("TOP", 0, -2)
text:SetPoint("BOTTOM", 0, 0)
text:SetJustifyH("TOP")
text:SetJustifyH("LEFT")
text:SetWordWrap(false)
local check = self:CreateRegion("Texture", "check", frame)
DiesalStyle:StyleTexture(check, {
position = { 1, nil, 0, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 10, 5, 16, 256, 128 }, "FFFF00" },
})
local arrow = self:CreateRegion("Texture", "arrow", frame)
DiesalStyle:StyleTexture(arrow, {
position = { nil, 2, -1, nil },
height = 16,
width = 16,
image = { "DiesalGUIcons", { 7, 5, 16, 256, 128 }, "FFFF00" },
})
-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for method, func in pairs(methods) do
self[method] = func
end
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return self
end
DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

@ -1,515 +0,0 @@
-- $Id: DiesalTools-1.0.lua 61 2017-03-28 23:13:41Z diesal2010 $
local MAJOR, MINOR = "DiesalTools-1.0", "$Rev: 61 $"
local DiesalTools, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalTools then return end -- No Upgrade needed.
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber, tostring = type, select, pairs, tonumber, tostring
local table_concat = table.concat
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper,gsub = string.sub, string.format, string.lower, string.upper, string.gsub
local floor, ceil, abs, modf = math.floor, math.ceil, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
-- ~~| Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local escapeSequences = {
[ "\a" ] = "\\a", -- Bell
[ "\b" ] = "\\b", -- Backspace
[ "\t" ] = "\\t", -- Horizontal tab
[ "\n" ] = "\\n", -- Newline
[ "\v" ] = "\\v", -- Vertical tab
[ "\f" ] = "\\f", -- Form feed
[ "\r" ] = "\\r", -- Carriage return
[ "\\" ] = "\\\\", -- Backslash
[ "\"" ] = "\\\"", -- Quotation mark
[ "|" ] = "||",
}
local lua_keywords = {
["and"] = true, ["break"] = true, ["do"] = true,
["else"] = true, ["elseif"] = true, ["end"] = true,
["false"] = true, ["for"] = true, ["function"] = true,
["if"] = true, ["in"] = true, ["local"] = true,
["nil"] = true, ["not"] = true, ["or"] = true,
["repeat"] = true, ["return"] = true, ["then"] = true,
["true"] = true, ["until"] = true, ["while"] = true
}
local sub_table = {
}
local colors = {
blue = '|cff'..'00aaff',
darkblue = '|cff'..'004466',
orange = '|cff'..'ffaa00',
darkorange = '|cff'..'4c3300',
grey = '|cff'..'7f7f7f',
darkgrey = '|cff'..'414141',
white = '|cff'..'ffffff',
red = '|cff'..'ff0000',
green = '|cff'..'00ff2b',
yellow = '|cff'..'ffff00',
lightyellow = '|cff'..'ffea7f',
}
local formattedArgs = {}
local function GetCaller(level)
-- ADDON:LogMessage(debugstack(10,2, 0))
for trace in debugstack(level,2, 0):gmatch("(.-)\n") do
-- Blizzard Sandbox
local match, _, file, line = trace:find("^.*\\(.-):(%d+)")
if match then return format('%s[%s%s: %s%s%s]|r',colors.orange,colors.yellow,file,colors.lightyellow,line,colors.orange) end
-- PQI DataFile
local match, _, file,line = trace:find('^%[string "[%s%-]*(.-%.lua).-"%]:(%d+)')
if match then return format('%s[%s%s: %s%s%s]|r',colors.orange,colors.yellow,file,colors.lightyellow,line,colors.orange) end
-- PQR Ability code
local match, _, file,line = trace:find('^%[string "(.-)"%]:(%d+)')
if match then return format('%s[%s%s: %s%s%s]|r',colors.orange,colors.yellow,file,colors.lightyellow,line,colors.orange) end
end
return format('%s[%sUnknown Caller%s]|r',colors.orange,colors.red,colors.orange)
end
local function round(number, base)
base = base or 1
return floor((number + base/2)/base) * base
end
local function getRGBColorValues(color,g,b)
if type(color) == 'number' and type(g) == 'number' and type(b) == 'number' then
if color <= 1 and g <= 1 and b <= 1 then
return round(color*255), round(g*255), round(b*255)
end
return color[1], color[2], color[3]
elseif type(color) == 'table' and type(color[1]) == 'number' and type(color[2]) == 'number' and type(color[3]) == 'number' then
if color[1] <= 1 and color[2] <= 1 and color[3] <= 1 then
return round(color[1]*255), round(color[2]*255), round(color[3]*255)
end
return color[1], color[2], color[3]
elseif type(color) == 'string' then
return tonumber(sub(color, 1, 2),16), tonumber(sub(color, 3, 4),16), tonumber(sub(color, 5, 6),16)
end
end
function DiesalTools.GetColor(value)
if not value then return end
if type(value) == 'table' and #value >= 3 then
return value[1]/255, value[2]/255, value[3]/255
elseif type(value) == 'string' then
return tonumber(sub(value,1,2),16)/255, tonumber(sub(value,3,4),16)/255, tonumber(sub(value,5,6),16)/255
end
end
-- ~~| API |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DiesalTools.Stack()
print("|r------------------------------| Stack Trace |-------------------------------")
local stack = debugstack(1,12, 0)
for trace in stack:gmatch("(.-)\n") do
match, _, file, line, func = trace:find("^.*\\(.-):(%d+).-`(.*)'$")
if match then print(format("%s[%s%s: %s%s%s] %sfunction|r %s|r",colors.orange,colors.yellow,file,colors.lightyellow,line,colors.orange,colors.blue,func)) end
end
print("|r--------------------------------------------------------------------------------")
end
--[[ copy = TableCopy(src, dest, metatable)
@Arguments:
dest Table to copy to
src Table to copy
metatable if true copies the metatable as well (boolean)
@Returns:
table copy of table
--]]
function DiesalTools.TableCopy(src,dest,metatable)
if type(src) == 'table' then
if not dest then dest = {} end
for sk, sv in next, src, nil do
dest[DiesalTools.TableCopy(sk)] = DiesalTools.TableCopy(sv)
end
if metatable then setmetatable(dest, DiesalTools.TableCopy(getmetatable(src))) end
else -- number, string, boolean, etc
dest = src
end
return dest
end
--[[ red, blue, green = GetColor(value)
@Arguments:
value Hex color code or a table contating R,G,B color values
@Returns:
red Red component of color (0-1) (number)
green Green component of color(0-1) (number)
blue Blue component of color (0-1) (number)
-- ]]
-- | Color Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- converts a color from RGB[0-1], RGB[0-255], HEX or HSL to RGB[0-1], RGB[0-255] or HEX
function DiesalTools.ConvertColor(from,to,v1,v2,v3)
if not from or not to or not v1 then return end
if type(v1) == 'table' then v1,v2,v3 = v1[1],v1[2],v1[3] end
local r, g, b
from, to = from:lower(), to:lower()
if from == 'rgb255' and type(v1) == 'number' and type(v2) == 'number' and type(v3) == 'number' then
r,g,b = v1, v2, v3
elseif from == 'rgb1' and type(v1) == 'number' and type(v2) == 'number' and type(v3) == 'number' then
r,g,b = round(v1*255), round(v2*255), round(v3*255)
elseif from == 'hex' and type(v1) == 'string' and #v1 > 5 then
r,g,b = tonumber(sub(v1, 1, 2),16), tonumber(sub(v1, 3, 4),16), tonumber(sub(v1, 5, 6),16)
elseif from == 'hsl' and type(v1) == 'number' and type(v2) == 'number' and type(v3) == 'number' then
if v2 == 0 then
v3 = round(v3 * 255)
r,g,b = v3,v3,v3
else
v1, v2, v3 = v1/360*6, min(max(0, v2), 1), min(max(0, v3), 1)
local c = (1-abs(2*v3-1))*v2
local x = (1-abs(v1%2-1))*c
local m = (v3-.5*c)
r,g,b = 0,0,0
if v1 < 1 then r,g,b = c,x,0
elseif v1 < 2 then r,g,b = x,c,0
elseif v1 < 3 then r,g,b = 0,c,x
elseif v1 < 4 then r,g,b = 0,x,c
elseif v1 < 5 then r,g,b = x,0,c
else r,g,b = c,0,x end
r,g,b = round((r+m)*255),round((g+m)*255),round((b+m)*255)
end
else
return
end
r,g,b = min(255,max(0,r)), min(255,max(0,g)), min(255,max(0,b))
if to == 'rgb255' then
return r,g,b
elseif to == 'rgb1' then
return r/255,g/255,b/255
elseif to == 'hex' then
return format("%02x%02x%02x",r,g,b)
end
end
-- Mixes a color with pure white to produce a lighter color
function DiesalTools.TintColor(color, percent, to, from)
percent = min(1,max(0,percent))
from, to = from or 'hex', to and to:lower() or 'hex'
local r,g,b = DiesalTools.ConvertColor(from,'rgb255',color)
if to == 'rgb255' then
return round((255-r)*percent+r), round((255-g)*percent+g), round((255-b)*percent+b)
elseif to == 'rgb1' then
return round( ((255-r)*percent+r) / 255 ), round( ((255-g)*percent+g) / 255 ), round( ((255-b)*percent+b) / 255 )
elseif to == 'hex' then
return format("%02x%02x%02x", round((255-r)*percent+r), round((255-g)*percent+g), round((255-b)*percent+b) )
end
-- return format("%02x%02x%02x", round((255-r)*percent+r), round((255-g)*percent+g), round((255-b)*percent+b) )
end
-- Mixes a color with pure black to produce a darker color
function DiesalTools.ShadeColor(color, percent, to, from)
percent = min(1,max(0,percent))
from, to = from or 'hex', to and to:lower() or 'hex'
local r,g,b = DiesalTools.ConvertColor(from,'rgb255',color)
if to == 'rgb255' then
return round(-r*percent+r), round(-g*percent+g), round(-b*percent+b)
elseif to == 'rgb1' then
return round( (-r*percent+r) / 255 ), round( (-g*percent+g) / 255 ), round( (-b*percent+b) / 255 )
elseif to == 'hex' then
return format("%02x%02x%02x", round(-r*percent+r), round(-g*percent+g), round(-b*percent+b) )
end
end
-- Mixes a color with the another color to produce an intermediate color.
function DiesalTools.MixColors(color1, color2, percent, to, from)
percent = min(1,max(0,percent))
from, to = from or 'hex', to and to:lower() or 'hex'
-- to = to and to:lower() or 'hex'
local r1, g1, b1 = DiesalTools.ConvertColor(from,'rgb255',color1)
local r2, g2, b2 = DiesalTools.ConvertColor(from,'rgb255',color2)
if to == 'rgb255' then
return round((r2-r1)*percent)+r1, round((g2-g1)*percent)+g1, round((b2-b1)*percent)+b1
elseif to == 'rgb1' then
return round( ((r2-r1)*percent+r1) / 255 ), round( ((g2-g1)*percent+g1) / 255 ), round( ((b2-b1)*percent+b1) / 255 )
elseif to == 'hex' then
return format("%02x%02x%02x", round((r2-r1)*percent)+r1, round((g2-g1)*percent)+g1, round((b2-b1)*percent)+b1 )
end
end
--- converts color HSL to HEX
function DiesalTools.HSL(v1,v2,v3)
if not v1 then return end
if type(v1) == 'table' then v1,v2,v3 = v1[1],v1[2],v1[3] end
local r, g, b
if v2 == 0 then
v3 = round(v3 * 255)
r,g,b = v3,v3,v3
else
v1, v2, v3 = v1/360*6, min(max(0, v2), 1), min(max(0, v3), 1)
local c = (1-abs(2*v3-1))*v2
local x = (1-abs(v1%2-1))*c
local m = (v3-.5*c)
r,g,b = 0,0,0
if v1 < 1 then r,g,b = c,x,0
elseif v1 < 2 then r,g,b = x,c,0
elseif v1 < 3 then r,g,b = 0,c,x
elseif v1 < 4 then r,g,b = 0,x,c
elseif v1 < 5 then r,g,b = x,0,c
else r,g,b = c,0,x end
r,g,b = round((r+m)*255),round((g+m)*255),round((b+m)*255)
end
r,g,b = min(255,max(0,r)), min(255,max(0,g)), min(255,max(0,b))
return format("%02x%02x%02x",r,g,b)
end
--[[ GetTxtColor(value)
@Arguments:
value Hex color code or a table contating R,G,B color values
@Returns:
text coloring escape sequence (|cFFFFFFFF)
-- ]]
function DiesalTools.GetTxtColor(value)
if not value then return end
if type(value) =='table' then value = string.format("%02x%02x%02x", value[1], value[2], value[3]) end
return format('|cff%s',value)
end
-- | Texture Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Get a piece of a texture as a cooridnate refernce
-- @Param column the column in the texture
-- @Param row the row in the texture
-- @Param size the size in the texture
-- @Param textureWidth total texture width
-- @Param textureHeight total texture height
-- @Return edge coordinates for image cropping, plugs directly into Texture:SetTexCoord(left, right, top, bottom) ]]
function DiesalTools.GetIconCoords(column,row,size,textureWidth,textureHeight)
size = size or 16
textureWidth = textureWidth or 128
textureHeight = textureHeight or 16
return (column * size - size) / textureWidth, (column * size) / textureWidth, (row * size - size) / textureHeight, (row * size) / textureHeight
end
-- | String Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Capitalize a string
-- @Param str the string to capatilize
-- @Return the capitilized string ]]
function DiesalTools.Capitalize(str)
return (str:gsub("^%l", upper))
end
--[[ Escape all formatting in a WoW-lua string
-- @Param str the string to escape
-- @Return the escaped string ]]
function DiesalTools.EscapeString(string)
return string:gsub( "[%z\1-\31\"\\|\127-\255]", escapeSequences )
end
--[[ ID = CreateID(s)
-- @Param s string to parse
-- @Return ID string stripped of all non letter characters and color codes.]]
function DiesalTools.CreateID(s)
return gsub(s:gsub('c%x%x%x%x%x%x%x%x', ''), '[^%a%d]', '')
end
--[[ str = TrimString(s)
-- @Param s string to parse
-- @Return str string stripped of leading and trailing spaces.]]
function DiesalTools.TrimString(s)
return s:gsub("^%s*(.-)%s*$", "%1")
end
--[[ string = SpliceString(string, start, End, txt)
@Arguments:
string string to splice
start starting index of splice
End ending index of splice
txt new text to splice in (string)
@Returns:
string resulting string of the splice
@example:
DiesalTools.SpliceString("123456789",2,4,'NEW') -- returns: "1NEW56789"
--]]
function DiesalTools.SpliceString(string,start,End,txt)
return string:sub(1, start-1)..txt..string:sub(End+1,-1)
end
--[[ string = Serialize(table)
@Param table - table to to serialize
@Return string - serialized table (string)
@deserialization:
local func,err = loadstring('serialized table')
if err then error(err) end
return func()
]]
local function serialize_number(number)
-- no argument checking - called very often
local text = ("%.17g"):format(number)
-- on the same platform tostring() and string.format()
-- return the same results for 1/0, -1/0, 0/0
-- so we don't need separate substitution table
return sub_table[text] or text
end
local function impl(t, cat, visited)
local t_type = type(t)
if t_type == "table" then
if not visited[t] then
visited[t] = true
cat("{")
-- Serialize numeric indices
local next_i = 0
for i, v in ipairs(t) do
if i > 1 then -- TODO: Move condition out of the loop
cat(",")
end
impl(v, cat, visited)
next_i = i
end
next_i = next_i + 1
-- Serialize hash part
-- Skipping comma only at first element iff there is no numeric part.
local need_comma = (next_i > 1)
for k, v in pairs(t) do
local k_type = type(k)
if k_type == "string" then
if need_comma then
cat(",")
end
need_comma = true
-- TODO: Need "%q" analogue, which would put quotes
-- only if string does not match regexp below
if not lua_keywords[k] and ("^[%a_][%a%d_]*$"):match(k) then
cat(k) cat("=")
else
cat(format("[%q]=", k))
end
impl(v, cat, visited)
else
if
k_type ~= "number" or -- non-string non-number
k >= next_i or k < 1 or -- integer key in hash part of the table
k % 1 ~= 0 -- non-integer key
then
if need_comma then
cat(",")
end
need_comma = true
cat("[")
impl(k, cat, visited)
cat("]=")
impl(v, cat, visited)
end
end
end
cat("}")
visited[t] = nil
else
-- this loses information on recursive tables
cat('"table (recursive)"')
end
elseif t_type == "number" then
cat(serialize_number(t))
elseif t_type == "boolean" then
cat(tostring(t))
elseif t == nil then
cat("nil")
else
-- this converts non-serializable (functions) types to strings
cat(format("%q", tostring(t)))
end
end
local function tstr_cat(cat, t)
impl(t, cat, {})
end
function DiesalTools.Serialize(t)
local buf = {}
local cat = function(v) buf[#buf + 1] = v end
impl(t, cat, {})
return format('return %s',table_concat(buf))
end
-- | Math Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Round a number
-- @Param number the number to round
-- @Param base the number to round to (can be a decimal) [Default:1]
-- @Return the rounded number to base ]]
function DiesalTools.Round(number, base)
base = base or 1
return floor((number + base/2)/base) * base
end
--[[ Round a number for printing
-- @Param number the number to round
-- @Param idp number of decimal points to round to [Default:1]
-- @Return the rounded number ]]
function DiesalTools.RoundPrint(num, idp)
return string.format("%." .. (idp or 0) .. "f", num)
end
-- | Frame Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ GetFrameQuadrant(frame)
@Arguments:
frame frame?!!
@Returns:
quadrant quadrant of the screen frames center is in
-- ]]
function DiesalTools.GetFrameQuadrant(frame)
if not frame:GetCenter() then return "UNKNOWN", frame:GetName() end
local x, y = frame:GetCenter()
local screenWidth = GetScreenWidth()
local screenHeight = GetScreenHeight()
local quadrant
if (x > (screenWidth / 4) and x < (screenWidth / 4)*3) and y > (screenHeight / 4)*3 then
quadrant = "TOP"
elseif x < (screenWidth / 4) and y > (screenHeight / 4)*3 then
quadrant = "TOPLEFT"
elseif x > (screenWidth / 4)*3 and y > (screenHeight / 4)*3 then
quadrant = "TOPRIGHT"
elseif (x > (screenWidth / 4) and x < (screenWidth / 4)*3) and y < (screenHeight / 4) then
quadrant = "BOTTOM"
elseif x < (screenWidth / 4) and y < (screenHeight / 4) then
quadrant = "BOTTOMLEFT"
elseif x > (screenWidth / 4)*3 and y < (screenHeight / 4) then
quadrant = "BOTTOMRIGHT"
elseif x < (screenWidth / 4) and (y > (screenHeight / 4) and y < (screenHeight / 4)*3) then
quadrant = "LEFT"
elseif x > (screenWidth / 4)*3 and y < (screenHeight / 4)*3 and y > (screenHeight / 4) then
quadrant = "RIGHT"
else
quadrant = "CENTER"
end
return quadrant
end
-- | Misc Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Pack(...) blizzard dosnt use 5.2 yet so will have to create this one
@Arguments:
... arguments to pack into a table
@Returns:
a new table with all parameters stored into keys 1, 2, etc. and with a field "n" with the total number of parameters
]]
function DiesalTools.Pack(...)
return { n = select("#", ...), ... }
end
--[[ Unpack(...)
@Arguments:
t table to unpack
@Returns:
... list of arguments
]]
function DiesalTools.Unpack(t)
if t.n then
return unpack(t,1,t.n)
end
return unpack(table)
end

@ -0,0 +1,581 @@
local MAJOR, MINOR = "DiesalTools-2.0", 1
---@alias Diesal.Tools DiesalTools-2.0
---@class DiesalTools-2.0
local DiesalTools = LibStub:NewLibrary(MAJOR, MINOR)
if not DiesalTools then
return
end -- No Upgrade needed.
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local type, select, pairs, tonumber, tostring = type, select, pairs, tonumber, tostring
local table_concat = table.concat
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper, gsub = string.sub, string.format, string.lower, string.upper, string.gsub
local floor, ceil, abs, modf = math.floor, math.ceil, math.abs, math.modf
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local CreateFrame, UIParent, GetCursorPosition = CreateFrame, UIParent, GetCursorPosition
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
-- ~~| Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local escapeSequences = {
["\a"] = "\\a", -- Bell
["\b"] = "\\b", -- Backspace
["\t"] = "\\t", -- Horizontal tab
["\n"] = "\\n", -- Newline
["\v"] = "\\v", -- Vertical tab
["\f"] = "\\f", -- Form feed
["\r"] = "\\r", -- Carriage return
["\\"] = "\\\\", -- Backslash
['"'] = '\\"', -- Quotation mark
["|"] = "||",
}
local lua_keywords = {
["and"] = true,
["break"] = true,
["do"] = true,
["else"] = true,
["elseif"] = true,
["end"] = true,
["false"] = true,
["for"] = true,
["function"] = true,
["if"] = true,
["in"] = true,
["local"] = true,
["nil"] = true,
["not"] = true,
["or"] = true,
["repeat"] = true,
["return"] = true,
["then"] = true,
["true"] = true,
["until"] = true,
["while"] = true,
}
local sub_table = {}
local colors = {
blue = "|cff" .. "00aaff",
darkblue = "|cff" .. "004466",
orange = "|cff" .. "ffaa00",
darkorange = "|cff" .. "4c3300",
grey = "|cff" .. "7f7f7f",
darkgrey = "|cff" .. "414141",
white = "|cff" .. "ffffff",
red = "|cff" .. "ff0000",
green = "|cff" .. "00ff2b",
yellow = "|cff" .. "ffff00",
lightyellow = "|cff" .. "ffea7f",
}
local formattedArgs = {}
---@param level number
local function GetCaller(level)
-- ADDON:LogMessage(debugstack(10,2, 0))
for trace in debugstack(level, 2, 0):gmatch("(.-)\n") do
-- Blizzard Sandbox
local match, _, file, line = trace:find("^.*\\(.-):(%d+)")
if match then
return format("%s[%s%s: %s%s%s]|r", colors.orange, colors.yellow, file, colors.lightyellow, line, colors.orange)
end
-- PQI DataFile
local match, _, file, line = trace:find('^%[string "[%s%-]*(.-%.lua).-"%]:(%d+)')
if match then
return format("%s[%s%s: %s%s%s]|r", colors.orange, colors.yellow, file, colors.lightyellow, line, colors.orange)
end
-- PQR Ability code
local match, _, file, line = trace:find('^%[string "(.-)"%]:(%d+)')
if match then
return format("%s[%s%s: %s%s%s]|r", colors.orange, colors.yellow, file, colors.lightyellow, line, colors.orange)
end
end
return format("%s[%sUnknown Caller%s]|r", colors.orange, colors.red, colors.orange)
end
local function round(number, base)
base = base or 1
return floor((number + base / 2) / base) * base
end
local function getRGBColorValues(color, g, b)
if type(color) == "number" and type(g) == "number" and type(b) == "number" then
if color <= 1 and g <= 1 and b <= 1 then
return round(color * 255), round(g * 255), round(b * 255)
end
return color[1], color[2], color[3]
elseif type(color) == "table" and type(color[1]) == "number" and type(color[2]) == "number" and type(color[3]) == "number" then
if color[1] <= 1 and color[2] <= 1 and color[3] <= 1 then
return round(color[1] * 255), round(color[2] * 255), round(color[3] * 255)
end
return color[1], color[2], color[3]
elseif type(color) == "string" then
return tonumber(sub(color, 1, 2), 16), tonumber(sub(color, 3, 4), 16), tonumber(sub(color, 5, 6), 16)
end
end
function DiesalTools.GetColor(value)
if not value then
return
end
if type(value) == "table" and #value >= 3 then
return value[1] / 255, value[2] / 255, value[3] / 255
elseif type(value) == "string" then
return tonumber(sub(value, 1, 2), 16) / 255, tonumber(sub(value, 3, 4), 16) / 255, tonumber(sub(value, 5, 6), 16) / 255
end
end
-- ~~| API |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DiesalTools.Stack()
print("|r------------------------------| Stack Trace |-------------------------------")
local stack = debugstack(1, 12, 0)
for trace in stack:gmatch("(.-)\n") do
local match, _, file, line, func = trace:find("^.*\\(.-):(%d+).-`(.*)'$")
if match then
print(format("%s[%s%s: %s%s%s] %sfunction|r %s|r", colors.orange, colors.yellow, file, colors.lightyellow, line, colors.orange, colors.blue, func))
end
end
print("|r--------------------------------------------------------------------------------")
end
--[[ copy = TableCopy(src, dest, metatable)
@Arguments:
dest Table to copy to
src Table to copy
metatable if true copies the metatable as well (boolean)
@Returns:
table copy of table
--]]
function DiesalTools.TableCopy(src, dest, metatable)
if type(src) == "table" then
if not dest then
dest = {}
end
for sk, sv in next, src, nil do
dest[DiesalTools.TableCopy(sk)] = DiesalTools.TableCopy(sv)
end
if metatable then
setmetatable(dest, DiesalTools.TableCopy(getmetatable(src)))
end
else -- number, string, boolean, etc
dest = src
end
return dest
end
--[[ red, blue, green = GetColor(value)
@Arguments:
value Hex color code or a table contating R,G,B color values
@Returns:
red Red component of color (0-1) (number)
green Green component of color(0-1) (number)
blue Blue component of color (0-1) (number)
-- ]]
-- | Color Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@alias ColorType 'rgb255' | 'rgb1' | 'hex' | 'hsl'
-- converts a color from RGB[0-1], RGB[0-255], HEX or HSL to RGB[0-1], RGB[0-255] or HEX
---@param from ColorType
---@param to ColorType
---@param v1 string | number | table
---@param v2? string | number
---@param v3? string | number
function DiesalTools.ConvertColor(from, to, v1, v2, v3)
if not from or not to or not v1 then
return
end
if type(v1) == "table" then
v1, v2, v3 = v1[1], v1[2], v1[3]
end
local r, g, b
from, to = from:lower(), to:lower()
if from == "rgb255" and type(v1) == "number" and type(v2) == "number" and type(v3) == "number" then
r, g, b = v1, v2, v3
elseif from == "rgb1" and type(v1) == "number" and type(v2) == "number" and type(v3) == "number" then
r, g, b = round(v1 * 255), round(v2 * 255), round(v3 * 255)
elseif from == "hex" and type(v1) == "string" and #v1 > 5 then
r, g, b = tonumber(sub(v1, 1, 2), 16), tonumber(sub(v1, 3, 4), 16), tonumber(sub(v1, 5, 6), 16)
elseif from == "hsl" and type(v1) == "number" and type(v2) == "number" and type(v3) == "number" then
if v2 == 0 then
v3 = round(v3 * 255)
r, g, b = v3, v3, v3
else
v1, v2, v3 = v1 / 360 * 6, min(max(0, v2), 1), min(max(0, v3), 1)
local c = (1 - abs(2 * v3 - 1)) * v2
local x = (1 - abs(v1 % 2 - 1)) * c
local m = (v3 - 0.5 * c)
r, g, b = 0, 0, 0
if v1 < 1 then
r, g, b = c, x, 0
elseif v1 < 2 then
r, g, b = x, c, 0
elseif v1 < 3 then
r, g, b = 0, c, x
elseif v1 < 4 then
r, g, b = 0, x, c
elseif v1 < 5 then
r, g, b = x, 0, c
else
r, g, b = c, 0, x
end
r, g, b = round((r + m) * 255), round((g + m) * 255), round((b + m) * 255)
end
else
return
end
r, g, b = min(255, max(0, r)), min(255, max(0, g)), min(255, max(0, b))
if to == "rgb255" then
return r, g, b
elseif to == "rgb1" then
return r / 255, g / 255, b / 255
elseif to == "hex" then
return format("%02x%02x%02x", r, g, b)
end
end
-- Mixes a color with pure white to produce a lighter color
function DiesalTools.TintColor(color, percent, to, from)
percent = min(1, max(0, percent))
from, to = from or "hex", to and to:lower() or "hex"
local r, g, b = DiesalTools.ConvertColor(from, "rgb255", color)
if to == "rgb255" then
return round((255 - r) * percent + r), round((255 - g) * percent + g), round((255 - b) * percent + b)
elseif to == "rgb1" then
return round(((255 - r) * percent + r) / 255), round(((255 - g) * percent + g) / 255), round(((255 - b) * percent + b) / 255)
elseif to == "hex" then
return format("%02x%02x%02x", round((255 - r) * percent + r), round((255 - g) * percent + g), round((255 - b) * percent + b))
end
-- return format("%02x%02x%02x", round((255-r)*percent+r), round((255-g)*percent+g), round((255-b)*percent+b) )
end
-- Mixes a color with pure black to produce a darker color
function DiesalTools.ShadeColor(color, percent, to, from)
percent = min(1, max(0, percent))
from, to = from or "hex", to and to:lower() or "hex"
local r, g, b = DiesalTools.ConvertColor(from, "rgb255", color)
if to == "rgb255" then
return round(-r * percent + r), round(-g * percent + g), round(-b * percent + b)
elseif to == "rgb1" then
return round((-r * percent + r) / 255), round((-g * percent + g) / 255), round((-b * percent + b) / 255)
elseif to == "hex" then
return format("%02x%02x%02x", round(-r * percent + r), round(-g * percent + g), round(-b * percent + b))
end
end
-- Mixes a color with the another color to produce an intermediate color.
function DiesalTools.MixColors(color1, color2, percent, to, from)
percent = min(1, max(0, percent))
from, to = from or "hex", to and to:lower() or "hex"
-- to = to and to:lower() or 'hex'
local r1, g1, b1 = DiesalTools.ConvertColor(from, "rgb255", color1)
local r2, g2, b2 = DiesalTools.ConvertColor(from, "rgb255", color2)
if to == "rgb255" then
return round((r2 - r1) * percent) + r1, round((g2 - g1) * percent) + g1, round((b2 - b1) * percent) + b1
elseif to == "rgb1" then
return round(((r2 - r1) * percent + r1) / 255), round(((g2 - g1) * percent + g1) / 255), round(((b2 - b1) * percent + b1) / 255)
elseif to == "hex" then
return format("%02x%02x%02x", round((r2 - r1) * percent) + r1, round((g2 - g1) * percent) + g1, round((b2 - b1) * percent) + b1)
end
end
--- converts color HSL to HEX
function DiesalTools.HSL(v1, v2, v3)
if not v1 then
return
end
if type(v1) == "table" then
v1, v2, v3 = v1[1], v1[2], v1[3]
end
local r, g, b
if v2 == 0 then
v3 = round(v3 * 255)
r, g, b = v3, v3, v3
else
v1, v2, v3 = v1 / 360 * 6, min(max(0, v2), 1), min(max(0, v3), 1)
local c = (1 - abs(2 * v3 - 1)) * v2
local x = (1 - abs(v1 % 2 - 1)) * c
local m = (v3 - 0.5 * c)
r, g, b = 0, 0, 0
if v1 < 1 then
r, g, b = c, x, 0
elseif v1 < 2 then
r, g, b = x, c, 0
elseif v1 < 3 then
r, g, b = 0, c, x
elseif v1 < 4 then
r, g, b = 0, x, c
elseif v1 < 5 then
r, g, b = x, 0, c
else
r, g, b = c, 0, x
end
r, g, b = round((r + m) * 255), round((g + m) * 255), round((b + m) * 255)
end
r, g, b = min(255, max(0, r)), min(255, max(0, g)), min(255, max(0, b))
return format("%02x%02x%02x", r, g, b)
end
--[[ GetTxtColor(value)
@Arguments:
value Hex color code or a table contating R,G,B color values
@Returns:
text coloring escape sequence (|cFFFFFFFF)
-- ]]
function DiesalTools.GetTxtColor(value)
if not value then
return
end
if type(value) == "table" then
value = string.format("%02x%02x%02x", value[1], value[2], value[3])
end
return format("|cff%s", value)
end
-- | Texture Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Get a piece of a texture as a cooridnate refernce
-- @Param column the column in the texture
-- @Param row the row in the texture
-- @Param size the size in the texture
-- @Param textureWidth total texture width
-- @Param textureHeight total texture height
-- @Return edge coordinates for image cropping, plugs directly into Texture:SetTexCoord(left, right, top, bottom) ]]
function DiesalTools.GetIconCoords(column, row, size, textureWidth, textureHeight)
size = size or 16
textureWidth = textureWidth or 128
textureHeight = textureHeight or 16
return (column * size - size) / textureWidth, (column * size) / textureWidth, (row * size - size) / textureHeight, (row * size) / textureHeight
end
-- | String Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Capitalize a string
-- @Param str the string to capatilize
-- @Return the capitilized string ]]
function DiesalTools.Capitalize(str)
return (str:gsub("^%l", upper))
end
--[[ Escape all formatting in a WoW-lua string
-- @Param str the string to escape
-- @Return the escaped string ]]
function DiesalTools.EscapeString(string)
return string:gsub('[%z\1-\31"\\|\127-\255]', escapeSequences)
end
--[[ ID = CreateID(s)
-- @Param s string to parse
-- @Return ID string stripped of all non letter characters and color codes.]]
function DiesalTools.CreateID(s)
return gsub(s:gsub("c%x%x%x%x%x%x%x%x", ""), "[^%a%d]", "")
end
--[[ str = TrimString(s)
-- @Param s string to parse
-- @Return str string stripped of leading and trailing spaces.]]
function DiesalTools.TrimString(s)
return s:gsub("^%s*(.-)%s*$", "%1")
end
--[[ string = SpliceString(string, start, End, txt)
@Arguments:
string string to splice
start starting index of splice
End ending index of splice
txt new text to splice in (string)
@Returns:
string resulting string of the splice
@example:
DiesalTools.SpliceString("123456789",2,4,'NEW') -- returns: "1NEW56789"
--]]
function DiesalTools.SpliceString(string, start, End, txt)
return string:sub(1, start - 1) .. txt .. string:sub(End + 1, -1)
end
--[[ string = Serialize(table)
@Param table - table to to serialize
@Return string - serialized table (string)
@deserialization:
local func,err = loadstring('serialized table')
if err then error(err) end
return func()
]]
local function serialize_number(number)
-- no argument checking - called very often
local text = ("%.17g"):format(number)
-- on the same platform tostring() and string.format()
-- return the same results for 1/0, -1/0, 0/0
-- so we don't need separate substitution table
return sub_table[text] or text
end
local function impl(t, cat, visited)
local t_type = type(t)
if t_type == "table" then
if not visited[t] then
visited[t] = true
cat("{")
-- Serialize numeric indices
local next_i = 0
for i, v in ipairs(t) do
if i > 1 then -- TODO: Move condition out of the loop
cat(",")
end
impl(v, cat, visited)
next_i = i
end
next_i = next_i + 1
-- Serialize hash part
-- Skipping comma only at first element iff there is no numeric part.
local need_comma = (next_i > 1)
for k, v in pairs(t) do
local k_type = type(k)
if k_type == "string" then
if need_comma then
cat(",")
end
need_comma = true
-- TODO: Need "%q" analogue, which would put quotes
-- only if string does not match regexp below
if not lua_keywords[k] and ("^[%a_][%a%d_]*$"):match(k) then
cat(k)
cat("=")
else
cat(format("[%q]=", k))
end
impl(v, cat, visited)
else
if
k_type ~= "number" -- non-string non-number
or k >= next_i
or k < 1 -- integer key in hash part of the table
or k % 1 ~= 0 -- non-integer key
then
if need_comma then
cat(",")
end
need_comma = true
cat("[")
impl(k, cat, visited)
cat("]=")
impl(v, cat, visited)
end
end
end
cat("}")
visited[t] = nil
else
-- this loses information on recursive tables
cat('"table (recursive)"')
end
elseif t_type == "number" then
cat(serialize_number(t))
elseif t_type == "boolean" then
cat(tostring(t))
elseif t == nil then
cat("nil")
else
-- this converts non-serializable (functions) types to strings
cat(format("%q", tostring(t)))
end
end
local function tstr_cat(cat, t)
impl(t, cat, {})
end
function DiesalTools.Serialize(t)
local buf = {}
local cat = function(v)
buf[#buf + 1] = v
end
impl(t, cat, {})
return format("return %s", table_concat(buf))
end
-- | Math Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Round a number
-- @Param number the number to round
-- @Param base the number to round to (can be a decimal) [Default:1]
-- @Return the rounded number to base ]]
---@param number number
---@param base? number
function DiesalTools.Round(number, base)
base = base or 1
return floor((number + base / 2) / base) * base
end
--[[ Round a number for printing
-- @Param number the number to round
-- @Param idp number of decimal points to round to [Default:1]
-- @Return the rounded number ]]
function DiesalTools.RoundPrint(num, idp)
return string.format("%." .. (idp or 0) .. "f", num)
end
-- | Frame Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ GetFrameQuadrant(frame)
@Arguments:
frame frame?!!
@Returns:
quadrant quadrant of the screen frames center is in
-- ]]
function DiesalTools.GetFrameQuadrant(frame)
if not frame:GetCenter() then
return "UNKNOWN", frame:GetName()
end
local x, y = frame:GetCenter()
local screenWidth = GetScreenWidth()
local screenHeight = GetScreenHeight()
local quadrant
if (x > (screenWidth / 4) and x < (screenWidth / 4) * 3) and y > (screenHeight / 4) * 3 then
quadrant = "TOP"
elseif x < (screenWidth / 4) and y > (screenHeight / 4) * 3 then
quadrant = "TOPLEFT"
elseif x > (screenWidth / 4) * 3 and y > (screenHeight / 4) * 3 then
quadrant = "TOPRIGHT"
elseif (x > (screenWidth / 4) and x < (screenWidth / 4) * 3) and y < (screenHeight / 4) then
quadrant = "BOTTOM"
elseif x < (screenWidth / 4) and y < (screenHeight / 4) then
quadrant = "BOTTOMLEFT"
elseif x > (screenWidth / 4) * 3 and y < (screenHeight / 4) then
quadrant = "BOTTOMRIGHT"
elseif x < (screenWidth / 4) and (y > (screenHeight / 4) and y < (screenHeight / 4) * 3) then
quadrant = "LEFT"
elseif x > (screenWidth / 4) * 3 and y < (screenHeight / 4) * 3 and y > (screenHeight / 4) then
quadrant = "RIGHT"
else
quadrant = "CENTER"
end
return quadrant
end
-- | Misc Tools |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--[[ Pack(...) blizzard dosnt use 5.2 yet so will have to create this one
@Arguments:
... arguments to pack into a table
@Returns:
a new table with all parameters stored into keys 1, 2, etc. and with a field "n" with the total number of parameters
]]
function DiesalTools.Pack(...)
return { n = select("#", ...), ... }
end
--[[ Unpack(...)
@Arguments:
t table to unpack
@Returns:
... list of arguments
]]
function DiesalTools.Unpack(t)
if t.n then
return unpack(t, 1, t.n)
end
return unpack(table)
end
Loading…
Cancel
Save