finished the essential of frame containers

This commit is contained in:
Tercio Jose
2023-04-20 09:49:28 -03:00
parent ca91c10ff8
commit daee366640
6 changed files with 532 additions and 149 deletions
+24 -10
View File
@@ -1,4 +1,11 @@
--uiobject: is an object that represents a UI element, such as a frame, a texture, or a button. UIObjects are the base class for all UI elements in the WoW API.
--3D World: is an object which is placed behind|below all UI elements, cannot be parent of any object, in the 3D World object is where the game world is rendered
--size: corresponds to the height and height of an object, it is measure in pixels, must be bigger than zero.
--scale: the size of an object is multiplied by this value, it is measure in percentage, must be between 0.65 and 2.40.
--alpha: corresponds to the transparency of an object, the bigger is the value less transparent is the object, it is measure in percentage, must be between 0 and 1, zero is fully transparent and one is fully opaque.
---@class _G
---@field RegisterAttributeDriver fun(statedriver: frame, attribute: string, conditional: string)
---@field RegisterStateDriver fun(statedriver: frame, attribute: string, conditional: string)
@@ -34,18 +41,19 @@
---@class unit : string string that represents a unit in the game, such as the player, a party member, or a raid member.
---@class health : number amount of hit points (health) of a unit. This value can be changed by taking damage or healing.
---@class role : string @string(TANK, HEALER, DAMAGER, NONE) is a string that represents the role of a unit, such as tank, healer, or damage dealer.
---@class point : string @string(topleft, topright, bottomleft, bottomright, top, bottom, left, right, center) is a string that represents a point on a frame. Points are used to position frames relative to each other.
---@class uiobject
---@field Show fun(self: uiobject)
---@field Hide fun(self: uiobject)
---@field SetShown fun(self: uiobject, state: boolean)
---@field IsShown fun(self: uiobject) : boolean
---@field SetAllPoints fun(self: uiobject)
---@field SetParent fun(self: uiobject, parent: frame)
---@field SetSize fun(self: uiobject, width: width|number, height: height|number)
---@field SetWidth fun(self: uiobject, width: width|number)
---@field SetHeight fun(self: uiobject, height: height|number)
---@field SetAlpha fun(self: uiobject, alpha: alpha|number)
---@field Show fun(self: uiobject) make the object be shown on the user screen
---@field Hide fun(self: uiobject) make the object be hidden from the user screen
---@field SetShown fun(self: uiobject, state: boolean) show or hide the object
---@field IsShown fun(self: uiobject) : boolean return if the object is shown or not
---@field SetAllPoints fun(self: uiobject) set the object to be the same size as its parent
---@field SetParent fun(self: uiobject, parent: frame) set the parent object of the object
---@field SetSize fun(self: uiobject, width: width|number, height: height|number) set the width and height of the object
---@field SetWidth fun(self: uiobject, width: width|number) set only the width of the object
---@field SetHeight fun(self: uiobject, height: height|number) set only the height of the object
---@field SetAlpha fun(self: uiobject, alpha: alpha|number) set the transparency of the object
---@field SetScale fun(self: uiobject, scale: scale|number)
---@field GetWidth fun(self: uiobject) : width|number
---@field GetHeight fun(self: uiobject) : height|number
@@ -54,6 +62,7 @@
---@field GetSize fun(self: uiobject) : width|number, height|number
---@field GetParent fun(self: uiobject) : frame
---@field GetPoint fun(self: uiobject, index: number): string, frame, string, number, number
---@field GetCenter fun(self: uiobject): number, number
---@field SetPoint fun(self: uiobject, point: "topleft"|"topright"|"bottomleft"|"bottomright"|"top"|"bottom"|"left"|"right"|"center", relativeFrame: uiobject, relativePoint: "topleft"|"topright"|"bottomleft"|"bottomright"|"top"|"bottom"|"left"|"right"|"center", xOffset: number, yOffset: number)
---@field ClearAllPoints fun(self: uiobject)
---@field CreateAnimationGroup fun(self: uiobject, name: string|nil, templateName: string|nil) : animationgroup
@@ -134,6 +143,7 @@
---@field EnableMouse fun(self: frame, enable: boolean)
---@field SetResizable fun(self: frame, enable: boolean)
---@field EnableMouseWheel fun(self: frame, enable: boolean)
---@field RegisterForDrag fun(self: frame, button: string)
---@field SetResizeBounds fun(self: frame, minWidth: number, minHeight: number, maxWidth: number, maxHeight: number)
---@class button : frame
@@ -156,6 +166,10 @@
---@field SetButtonState fun(self: button, state: string, enable: boolean)
---@field GetButtonState fun(self: button, state: string) : boolean
---@field RegisterForClicks fun(self: button, button1: nil|"AnyUp"|"AnyDown"|"LeftButtonDown"|"LeftButtonUp"|"MiddleButtonUp"|"MiddleButtonDown"|"RightButtonDown"|"RightButtonUp"|"Button4Up"|"Button4Down"|"Button5Up"|"Button5Down", button2: nil|"AnyUp"|"AnyDown"|"LeftButtonDown"|"LeftButtonUp"|"MiddleButtonUp"|"MiddleButtonDown"|"RightButtonDown"|"RightButtonUp"|"Button4Up"|"Button4Down"|"Button5Up"|"Button5Down")
---@field GetNormalTexture fun(self: button) : texture
---@field GetPushedTexture fun(self: button) : texture
---@field GetHighlightTexture fun(self: button) : texture
---@field GetDisabledTexture fun(self: button) : texture
---@class statusbar : frame
---@field SetStatusBarColor fun(self: statusbar, r: red|number, g: green|number, b: blue|number, a: alpha|number)
+410 -106
View File
@@ -8,84 +8,81 @@ local _
local DF = detailsFramework
local CreateFrame = CreateFrame
local wipe = wipe
local unpack = unpack
---@class framecontainer : frame
---@class dfframecontainer : frame, dfframecontainermixin, dfoptionsmixin
---@field bIsSizing boolean
---@field options table
---@field leftResizer button
---@field rightResizer button
---@field OnSizeChanged fun(frameContainer: framecontainer)
---@field currentWidth number
---@field currentHeight number
---@field bottomLeftResizer framecontainerresizer
---@field bottomRightResizer framecontainerresizer
---@field topLeftResizer framecontainerresizer
---@field topRightResizer framecontainerresizer
---@field topResizer framecontainerresizer
---@field bottomResizer framecontainerresizer
---@field leftResizer framecontainerresizer
---@field rightResizer framecontainerresizer
---@field cornerResizers framecontainerresizer[]
---@field sideResizers framecontainerresizer[]
---@field components table<frame, boolean>
---@field moverFrame frame
---@field movableChildren frame[]
---@field OnSizeChanged fun(frameContainer: dfframecontainer)
---@field OnResizerMouseDown fun(resizerButton: button, mouseButton: string)
---@field OnResizerMouseUp fun(resizerButton: button, mouseButton: string)
---@field HideResizer fun(frameContainer: framecontainer)
---@field ShowResizer fun(frameContainer: framecontainer)
---@field OnInitialize fun(frameContainer: framecontainer)
---@field SetLocked fun(frameContainer: framecontainer, isLocked: boolean)
---@field CheckLockedState fun(frameContainer: framecontainer)
---@field HideResizer fun(frameContainer: dfframecontainer)
---@field ShowResizer fun(frameContainer: dfframecontainer)
---@field OnInitialize fun(frameContainer: dfframecontainer)
---@field SetResizeLocked fun(frameContainer: dfframecontainer, isLocked: boolean)
---@field SetMovableLocked fun(frameContainer: dfframecontainer, isLocked: boolean)
---@field CheckResizeLockedState fun(frameContainer: dfframecontainer)
---@field CheckMovableLockedState fun(frameContainer: dfframecontainer)
---@field CreateMover fun(frameContainer: dfframecontainer)
---@field CreateResizers fun(frameContainer: dfframecontainer)
---@field RegisterChildForDrag fun(frameContainer: dfframecontainer, child: frame)
---@field UnregisterChildForDrag fun(frameContainer: dfframecontainer, child: frame)
---@field RefreshChildrenState fun(frameContainer: dfframecontainer)
---@field OnChildDragStart fun(frameContainer: dfframecontainer, child: frame)
---@field OnChildDragStop fun(frameContainer: dfframecontainer, child: frame)
detailsFramework.frameContainerMixin = {
---@class framecontainerresizer : button
---@field sizingFrom string
---@class dfframecontainermixin
detailsFramework.FrameContainerMixin = {
--methods
---run when the container has its size changed
---@param frameContainer framecontainer
OnSizeChanged = function(frameContainer)
---@type frame[]
local children = {frameContainer:GetChildren()}
---@type number
local childrenAmount = #children
--get the width of each children and sum the values, do the same thing for height
---@type number
local childrenWidth = 0
---@type number
local childrenHeight = 0
for i = 1, childrenAmount do
childrenWidth = childrenWidth + children[i]:GetWidth()
childrenHeight = childrenHeight + children[i]:GetHeight()
end
print("running...")
--if the children width is bigger than the container width, then need to resize the width of the children to porportionally fit the container
--this resize is done by getting the width of each child and reduce the width of the child by the percentage of the difference between the container width and the children width
if childrenWidth > frameContainer:GetWidth() then
---@type number
local widthDifference = childrenWidth - frameContainer:GetWidth()
for i = 1, childrenAmount do
children[i]:SetWidth(children[i]:GetWidth() - (children[i]:GetWidth() * (widthDifference / childrenWidth)))
end
end
end,
---run when the user click on the resizer
---@param resizerButton button
---@param resizerButton framecontainerresizer
---@param mouseButton string
OnResizerMouseDown = function(resizerButton, mouseButton)
if (mouseButton ~= "LeftButton") then
return
end
print(1)
---@type framecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `framecontainer`. .. but framecontainer is inherited from frame
---@type dfframecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `dfframecontainer`. .. but dfframecontainer is inherited from frame
if (frameContainer.bIsSizing) then
return
end
frameContainer.bIsSizing = true
frameContainer:StartSizing("bottomright")
frameContainer:StartSizing(resizerButton.sizingFrom)
end,
---run when the user click on the resizer
---@param resizerButton button
---@param resizerButton framecontainerresizer
---@param mouseButton string
OnResizerMouseUp = function(resizerButton, mouseButton)
---@type framecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `framecontainer`. .. but framecontainer is inherited from frame
print(2)
---@type dfframecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `dfframecontainer`. .. but dfframecontainer is inherited from frame
if (not frameContainer.bIsSizing) then
print("fuck")
return
end
@@ -94,15 +91,41 @@ print(1)
end,
---hide resizer
---@param frameContainer framecontainer
---@param frameContainer dfframecontainer
HideResizer = function(frameContainer)
frameContainer.leftResizer:Hide()
frameContainer.rightResizer:Hide()
for i = 1, #frameContainer.cornerResizers do
frameContainer.cornerResizers[i]:Hide()
end
for i = 1, #frameContainer.sideResizers do
frameContainer.sideResizers[i]:Hide()
end
end,
---show resizer
---@param frameContainer framecontainer
---@param frameContainer dfframecontainer
ShowResizer = function(frameContainer)
--corner resizers
if (frameContainer.options.use_bottomleft_resizer) then
frameContainer.bottomLeftResizer:Show()
end
if (frameContainer.options.use_bottomright_resizer) then
frameContainer.bottomRightResizer:Show()
end
if (frameContainer.options.use_topleft_resizer) then
frameContainer.topRightResizer:Show()
end
if (frameContainer.options.use_topright_resizer) then
frameContainer.topRightResizer:Show()
end
--side resizers
if (frameContainer.options.use_top_resizer) then
frameContainer.topResizer:Show()
end
if (frameContainer.options.use_bottom_resizer) then
frameContainer.bottomResizer:Show()
end
if (frameContainer.options.use_left_resizer) then
frameContainer.leftResizer:Show()
end
@@ -112,110 +135,391 @@ print(1)
end,
---check the lock state and show or hide the resizer, set the frame as movable or not, resizeable or not
---@param frameContainer framecontainer
CheckLockedState = function(frameContainer)
if (frameContainer.options.is_locked) then
frameContainer:HideResizer()
frameContainer:EnableMouse(false)
frameContainer:SetResizable(false)
else
---@param frameContainer dfframecontainer
CheckResizeLockedState = function(frameContainer)
if (frameContainer.options.can_resize) then
frameContainer:ShowResizer()
frameContainer:EnableMouse(true)
frameContainer:SetResizable(true)
else
frameContainer:HideResizer()
frameContainer:SetResizable(false)
end
end,
---check if the framecontainer can be moved and show or hide the mover
---@param frameContainer dfframecontainer
CheckMovableLockedState = function(frameContainer)
if (frameContainer.options.can_move) then
frameContainer:SetMovable(true)
frameContainer:EnableMouse(true)
frameContainer.moverFrame:Show()
else
frameContainer:SetMovable(false)
frameContainer:EnableMouse(false)
frameContainer.moverFrame:Hide()
end
end,
---set the lock state
---@param frameContainer framecontainer
---@param frameContainer dfframecontainer
---@param isLocked boolean
SetLocked = function(frameContainer, isLocked)
frameContainer.options.is_locked = isLocked
frameContainer:CheckLockedState()
SetResizeLocked = function(frameContainer, isLocked)
frameContainer.options.can_resize = not isLocked
frameContainer:CheckResizeLockedState()
end,
---set the state of the mover frame
---@param frameContainer dfframecontainer
---@param isLocked boolean
SetMovableLocked = function(frameContainer, isLocked)
frameContainer.options.can_move = not isLocked
frameContainer:CheckMovableLockedState()
end,
---create a mover to move the frame
---@param frameContainer dfframecontainer
CreateMover = function(frameContainer)
local mover = CreateFrame("button", nil, frameContainer)
frameContainer.moverFrame = mover
mover:SetAllPoints(frameContainer)
mover:SetMovable(true)
mover:SetScript("OnMouseDown", function(self, mouseButton)
if (mouseButton ~= "LeftButton" or not frameContainer.options.can_move) then
return
end
frameContainer:StartMoving()
end)
mover:SetScript("OnMouseUp", function(self, mouseButton)
if (mouseButton ~= "LeftButton" or not frameContainer.options.can_move) then
return
end
frameContainer:StopMovingOrSizing()
end)
end,
---create four corner resizer and four side resizer
---@param frameContainer dfframecontainer
CreateResizers = function(frameContainer)
local parent = frameContainer:GetParent()
--create resizers for the container corners
local bottomLeftResizer, bottomRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "BottomLeftResizer", parent:GetName() .. "BottomRightResizer")
frameContainer.bottomLeftResizer = bottomLeftResizer
frameContainer.bottomRightResizer = bottomRightResizer
local topLeftResizer, topRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopLeftResizer", parent:GetName() .. "TopRightResizer")
frameContainer.topLeftResizer = topLeftResizer
frameContainer.topRightResizer = topRightResizer
local topResizer, bottomResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopResizer", parent:GetName() .. "BottomResizer")
frameContainer.topResizer = topResizer
frameContainer.bottomResizer = bottomResizer
local leftResizer, rightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "LeftResizer", parent:GetName() .. "TopResizer")
frameContainer.leftResizer = leftResizer
frameContainer.rightResizer = rightResizer
frameContainer.cornerResizers = {
bottomLeftResizer,
bottomRightResizer,
topLeftResizer,
topRightResizer,
}
frameContainer.sideResizers = {
topResizer,
bottomResizer,
leftResizer,
rightResizer,
}
--add all resizers to the frameContainer.components table
for i = 1, #frameContainer.cornerResizers do
frameContainer.components[frameContainer.cornerResizers[i]] = true
frameContainer.cornerResizers[i]:SetFrameStrata("TOOLTIP")
end
for i = 1, #frameContainer.sideResizers do
frameContainer.components[frameContainer.sideResizers[i]] = true
frameContainer.sideResizers[i]:SetFrameStrata("TOOLTIP")
end
end,
---run when the container is created
---@param frameContainer framecontainer
OnInitialize = function(frameContainer)
frameContainer.leftResizer:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.leftResizer:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
frameContainer.rightResizer:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.rightResizer:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
---@param frameContainer dfframecontainer
OnInitialize = function(frameContainer) --õninit ~init ~oninit
--set the default members
frameContainer.bIsSizing = false
frameContainer:SetSize(frameContainer.options.width, frameContainer.options.height)
if (frameContainer.options.is_locked) then
frameContainer:HideResizer()
else
frameContainer:ShowResizer()
--iterate among the corner resizers and set the mouse down and up scripts
for i = 1, #frameContainer.cornerResizers do
frameContainer.cornerResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.cornerResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
end
frameContainer:CheckLockedState()
local sideResizeThickness = 3
--iterate among the side resizers and set the mouse down and up scripts; set the texture color; clear all points; set the thickness
for i = 1, #frameContainer.sideResizers do
frameContainer.sideResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.sideResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
frameContainer.sideResizers[i]:GetNormalTexture():SetColorTexture(1, 1, 1, 0.6)
frameContainer.sideResizers[i]:GetHighlightTexture():SetColorTexture(detailsFramework:ParseColors("aqua"))
frameContainer.sideResizers[i]:GetPushedTexture():SetColorTexture(1, 1, 1, 1)
frameContainer.sideResizers[i]:ClearAllPoints()
--can use SetSize here because the width or height are set by the point, e.g. 'topleft' to 'topright' overwrite the width set here
frameContainer.sideResizers[i]:SetSize(sideResizeThickness, sideResizeThickness)
end
--flip the corner resizers texturess
frameContainer.topLeftResizer:GetNormalTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topLeftResizer:GetHighlightTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topLeftResizer:GetPushedTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topRightResizer:GetNormalTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topRightResizer:GetHighlightTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topRightResizer:GetPushedTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topLeftResizer:ClearAllPoints()
frameContainer.topLeftResizer:SetPoint("topleft", frameContainer, "topleft", 0, 0)
frameContainer.topRightResizer:ClearAllPoints()
frameContainer.topRightResizer:SetPoint("topright", frameContainer, "topright", 0, 0)
--resize from for the corner resizers
frameContainer.bottomLeftResizer.sizingFrom = "bottomleft"
frameContainer.bottomRightResizer.sizingFrom = "bottomright"
frameContainer.topLeftResizer.sizingFrom = "topleft"
frameContainer.topRightResizer.sizingFrom = "topright"
--resize from for the side resizers
frameContainer.topResizer.sizingFrom = "top"
frameContainer.bottomResizer.sizingFrom = "bottom"
frameContainer.leftResizer.sizingFrom = "left"
frameContainer.rightResizer.sizingFrom = "right"
--set the side resizer points
frameContainer.topResizer:SetPoint("topleft", frameContainer, "topleft", 0, 0)
frameContainer.topResizer:SetPoint("topright", frameContainer, "topright", 0, 0)
frameContainer.bottomResizer:SetPoint("bottomleft", frameContainer, "bottomleft", 0, 0)
frameContainer.bottomResizer:SetPoint("bottomright", frameContainer, "bottomright", 0, 0)
frameContainer.leftResizer:SetPoint("topleft", frameContainer, "topleft", 0, 0)
frameContainer.leftResizer:SetPoint("bottomleft", frameContainer, "bottomleft", 0, 0)
frameContainer.rightResizer:SetPoint("topright", frameContainer, "topright", 0, 0)
frameContainer.rightResizer:SetPoint("bottomright", frameContainer, "bottomright", 0, 0)
if (frameContainer.options.can_resize) then
frameContainer:ShowResizer()
else
frameContainer:HideResizer()
end
frameContainer:CheckResizeLockedState()
frameContainer:CheckMovableLockedState()
frameContainer:SetResizeBounds(50, 50, 1000, 1000)
end,
---run when the container has its size changed
---@param frameContainer dfframecontainer
OnSizeChanged = function(frameContainer)
---@type frame[]
local children = {frameContainer:GetChildren()}
---@type number
local childrenAmount = #children
--get the container size before its size was changed and calculate the percent of the difference between the old size and the new size
--adding +1 to the width and height difference to prevent the child from shrinking to 0, so it is scaled by 1
---@type number
local widthDifference = 1 + (frameContainer:GetWidth() - frameContainer.currentWidth) / frameContainer.currentWidth
---@type number
local heightDifference = 1 + (frameContainer:GetHeight() - frameContainer.currentHeight) / frameContainer.currentHeight
for i = 1, childrenAmount do
---@type frame
local child = children[i]
--if the child is a component, skip it
if (not frameContainer.components[child]) then
child:SetWidth(child:GetWidth() * widthDifference)
child:SetHeight(child:GetHeight() * heightDifference)
end
end
--update the current size of the container
frameContainer.currentWidth = frameContainer:GetWidth()
frameContainer.currentHeight = frameContainer:GetHeight()
end,
OnChildDragStop = function(child)
child:StopMovingOrSizing()
child:SetScript("OnUpdate", nil)
end,
OnChildDragStart = function(child)
---@type dfframecontainer
local frameContainer = child:GetParent()
---get the coordinates for the frame container, which is called 'boundingBox' for convenience
---@type objectcoordinates
local boundingBox = detailsFramework:GetObjectCoordinates(frameContainer)
child:StartMoving()
--save the current point of the child, so it can be restored if the child is dragged outside the container
local childPoints = {}
for pointIndex = 1, child:GetNumPoints() do
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
end
child:SetScript("OnUpdate", function(self)
---@type objectcoordinates
local childPos = detailsFramework:GetObjectCoordinates(self)
--check if the borders of the rectangle 'rec' collided with the borders of the rectangle 'bbox'
if ((childPos.left < boundingBox.left or childPos.right > boundingBox.right) or (childPos.top > boundingBox.top or childPos.bottom < boundingBox.bottom)) then
child:ClearAllPoints()
for pointIndex = 1, #childPoints do
child:SetPoint(unpack(childPoints[pointIndex]))
end
else
wipe(childPoints)
for pointIndex = 1, child:GetNumPoints() do
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
end
end
end)
end,
---check if the children can be moved and set the properties on thisFrame
---@param frameContainer dfframecontainer
RefreshChildrenState = function(frameContainer)
frameContainer:EnableMouse(true)
if (frameContainer.options.can_move_children) then
for child, _ in pairs(frameContainer.movableChildren) do
child:EnableMouse(true)
child:SetMovable(true)
child:RegisterForDrag("LeftButton")
child:SetScript("OnDragStart", detailsFramework.FrameContainerMixin.OnChildDragStart)
child:SetScript("OnDragStop", detailsFramework.FrameContainerMixin.OnChildDragStop)
end
else
for child, _ in pairs(frameContainer.movableChildren) do
child:EnableMouse(false)
child:SetMovable(false)
child:RegisterForDrag("")
child:SetScript("OnDragStart", nil)
child:SetScript("OnDragStop", nil)
end
end
end,
RegisterChildForDrag = function(frameContainer, child)
frameContainer.movableChildren[child] = true
frameContainer:RefreshChildrenState()
end,
UnregisterChildForDrag = function(frameContainer, child)
frameContainer.movableChildren[child] = nil
frameContainer:RefreshChildrenState()
end,
}
---these are the default settings for the frame container; these keys can be accessed by dfframecontainer.options[key]
---@type table<string, any>
local frameContainerOptions = {
--default settings
width = 300,
height = 150,
is_locked = false,
can_resize = false, --can or not be resized
can_move = false, --can or not be moved
can_move_children = true,
use_topleft_resizer = false,
use_topright_resizer = false,
use_bottomleft_resizer = false,
use_bottomright_resizer = true,
use_top_resizer = false,
use_bottom_resizer = false,
use_left_resizer = false,
use_right_resizer = true,
use_right_resizer = false,
}
---create a frame container, which is a frame that envelops another frame, and can be moved, resized, etc.
---@param parent frame
---@param options table|nil
---@param frameName string|nil
---@return framecontainer
---@return dfframecontainer
function DF:CreateFrameContainer(parent, options, frameName)
---@type framecontainer
local container = CreateFrame("frame", frameName or ("$parentFrameContainer" .. math.random(10000, 99999)), parent, "BackdropTemplate")
---@type dfframecontainer
local frameContainer = CreateFrame("frame", frameName or ("$parentFrameContainer" .. math.random(10000, 99999)), parent, "BackdropTemplate")
frameContainer.components = {}
frameContainer.movableChildren = {}
detailsFramework:Mixin(container, detailsFramework.frameContainerMixin)
detailsFramework:Mixin(container, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(frameContainer, detailsFramework.FrameContainerMixin)
detailsFramework:Mixin(frameContainer, detailsFramework.OptionsFunctions)
detailsFramework:CreateResizeGrips(container)
frameContainer:CreateResizers()
frameContainer:CreateMover()
frameContainer:BuildOptionsTable(frameContainerOptions, options)
container:BuildOptionsTable(frameContainerOptions, options)
frameContainer:OnInitialize()
container:SetScript("OnSizeChanged", container.OnSizeChanged)
frameContainer.currentWidth = frameContainer:GetWidth()
frameContainer.currentHeight = frameContainer:GetHeight()
frameContainer:SetScript("OnSizeChanged", frameContainer.OnSizeChanged)
container.bIsSizing = false
container:OnInitialize()
return container
return frameContainer
end
function DF:CreateFrameContainerTest(parent, options, frameName)
function DF:CreateFrameContainerTest(parent, options, frameName)
local container = DF:CreateFrameContainer(parent, options, frameName)
container:SetSize(400, 400)
container:SetPoint("center", UIParent, "center", 0, 0)
container:SetPoint("center", _G.UIParent, "center", 0, 0)
detailsFramework:ApplyStandardBackdrop(container)
for i = 1, 3 do
for o = 1, 3 do
local frame = CreateFrame("frame", "$parentFrame" .. math.random(10000, 99999), container, "BackdropTemplate")
frame:SetBackdrop({bgFile = "Interface\\AddOns\\Details\\images\\background", tile = true, tileSize = 16, edgeFile = "Interface\\AddOns\\Details\\images\\border_2", edgeSize = 16, insets = {left = 4, right = 4, top = 4, bottom = 4}})
local verticalLastBox = nil
for i = 1, 4 do
local lastBox = nil
for o = 1, 4 do
local frame = CreateFrame("frame", "$parentFrame" .. i .. o, container, "BackdropTemplate")
container:RegisterChildForDrag(frame)
frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
frame:SetBackdropColor(0, 0, 0, 0.5)
frame:SetBackdropBorderColor(1, 1, 1, 0.5)
frame:SetSize(100, 100)
frame:SetPoint("TOPLEFT", container, "TOPLEFT", 10 + (i - 1) * 110, -10 - (o - 1) * 110)
frame:SetSize(98, 98)
if (lastBox) then
frame:SetPoint("TOPLEFT", lastBox, "topright", 1, 0)
else
if (verticalLastBox) then
frame:SetPoint("TOPLEFT", verticalLastBox, "bottomleft", 0, -1)
verticalLastBox = frame
else
local x = 1 + (o - 1) * 99
local y = -10 - (i - 1) * 99
frame:SetPoint("TOPLEFT", container, "TOPLEFT", x, y)
verticalLastBox = frame
end
end
lastBox = frame
end
end
C_Timer.After(2, function()
--container:SetResizeLocked(true)
end)
end
C_Timer.After(2, function()
--DetailsFramework:CreateFrameContainerTest(UIParent)
end)
--C_Timer.After(2, function()
-- DetailsFramework:CreateFrameContainerTest(UIParent)
--end)
--[=[
/run DetailsFramework:CreateFrameContainerTest(UIParent)
C_Timer.After(2, function()
DetailsFramework:CreateFrameContainerTest(UIParent)
end)
end)
--]=]
+50
View File
@@ -121,6 +121,56 @@ function DF:Round(num, numDecimalPlaces)
return math.floor(num * mult + 0.5) / mult
end
local BoundingBox = {}
BoundingBox.CoordinatesData = {
["topleft"] = {["x"] = 'number', ["y"] = 'number'},
["topright"] = {["x"] = 'number', ["y"] = 'number'},
["bottomleft"] = {["x"] = 'number', ["y"] = 'number'},
["bottomright"] = {["x"] = 'number', ["y"] = 'number'},
["center"] = {["x"] = 'number', ["y"] = 'number'},
["width"] = 'number',
["height"] = 'number',
}
---@class objectcoordinates
---@field topleft {["x"]: number, ["y"]: number}
---@field topright {["x"]: number, ["y"]: number}
---@field bottomleft {["x"]: number, ["y"]: number}
---@field bottomright {["x"]: number, ["y"]: number}
---@field center {["x"]: number, ["y"]: number}
---@field width number
---@field height number
---@field left number
---@field right number
---@field top number
---@field bottom number
---return the coordinates of the four corners of an object
---@param object uiobject
---@return objectcoordinates
function DF:GetObjectCoordinates(object)
local centerX, centerY = object:GetCenter()
local width = object:GetWidth()
local height = object:GetHeight()
local halfWidth = width / 2
local halfHeight = height / 2
return {
["width"] = width,
["height"] = height,
["left"] = centerX - halfWidth,
["right"] = centerX + halfWidth,
["top"] = centerY + halfHeight,
["bottom"] = centerY - halfHeight,
["center"] = {x = centerX, y = centerY},
["topleft"] = {x = centerX - halfWidth, y = centerY + halfHeight},
["topright"] = {x = centerX + halfWidth, y = centerY + halfHeight},
["bottomleft"] = {x = centerX - halfWidth, y = centerY - halfHeight},
["bottomright"] = {x = centerX + halfWidth, y = centerY - halfHeight},
}
end
function DF:ScaleBack()
end
+1
View File
@@ -268,6 +268,7 @@ detailsFramework.SetPointMixin = {
}
---mixin for options
---@class dfoptionsmixin
detailsFramework.OptionsFunctions = {
SetOption = function(self, optionName, optionValue)
if (self.options) then
+27 -29
View File
@@ -3919,43 +3919,41 @@ local rezieGripOptions = {
---create the two resize grips for a frame, one in the bottom left and another in the bottom right
---@param parent frame
---@param options table|nil
---@param leftResizerName string|nil
---@param rightResizerName string|nil
---@return frame, frame
function detailsFramework:CreateResizeGrips(parent, options, frameName)
if (parent) then
local parentName = parent:GetName()
function detailsFramework:CreateResizeGrips(parent, options, leftResizerName, rightResizerName)
local parentName = parent:GetName()
local leftResizer = CreateFrame("button", frameName or (parentName and "$parentLeftResizer"), parent, "BackdropTemplate")
local rightResizer = CreateFrame("button", frameName or (parentName and "$parentRightResizer"), parent, "BackdropTemplate")
local leftResizer = _G.CreateFrame("button", leftResizerName or (parentName and "$parentLeftResizer"), parent, "BackdropTemplate")
local rightResizer = _G.CreateFrame("button", rightResizerName or (parentName and "$parentRightResizer"), parent, "BackdropTemplate")
parent.leftResizer = leftResizer
parent.rightResizer = rightResizer
detailsFramework:Mixin(leftResizer, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(rightResizer, detailsFramework.OptionsFunctions)
leftResizer:BuildOptionsTable(rezieGripOptions, options)
rightResizer:BuildOptionsTable(rezieGripOptions, options)
detailsFramework:Mixin(leftResizer, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(rightResizer, detailsFramework.OptionsFunctions)
leftResizer:BuildOptionsTable(rezieGripOptions, options)
rightResizer:BuildOptionsTable(rezieGripOptions, options)
leftResizer:SetPoint("bottomleft", parent, "bottomleft", 0, 0)
rightResizer:SetPoint("bottomright", parent, "bottomright", 0, 0)
leftResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
rightResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
leftResizer:SetPoint("bottomleft", parent, "bottomleft", 0, 0)
rightResizer:SetPoint("bottomright", parent, "bottomright", 0, 0)
leftResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
rightResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
rightResizer:SetNormalTexture(rightResizer.options.normal_texture)
rightResizer:SetHighlightTexture(rightResizer.options.highlight_texture)
rightResizer:SetPushedTexture(rightResizer.options.pushed_texture)
rightResizer:SetNormalTexture(rightResizer.options.normal_texture)
rightResizer:SetHighlightTexture(rightResizer.options.highlight_texture)
rightResizer:SetPushedTexture(rightResizer.options.pushed_texture)
leftResizer:SetNormalTexture(leftResizer.options.normal_texture)
leftResizer:SetHighlightTexture(leftResizer.options.highlight_texture)
leftResizer:SetPushedTexture(leftResizer.options.pushed_texture)
leftResizer:SetNormalTexture(leftResizer.options.normal_texture)
leftResizer:SetHighlightTexture(leftResizer.options.highlight_texture)
leftResizer:SetPushedTexture(leftResizer.options.pushed_texture)
if (leftResizer.options.should_mirror_left_texture) then
leftResizer:GetNormalTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetHighlightTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetPushedTexture():SetTexCoord(1, 0, 0, 1)
end
return leftResizer, rightResizer
if (leftResizer.options.should_mirror_left_texture) then
leftResizer:GetNormalTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetHighlightTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetPushedTexture():SetTexCoord(1, 0, 0, 1)
end
return leftResizer, rightResizer
end
+20 -4
View File
@@ -1258,13 +1258,28 @@ end
---@param tabFrame tabframe
---@return breakdownspellscrollframe
function spellsTab.CreateSpellScrollContainer(tabFrame)
--create a container for the scrollframe
local options = {
width = CONST_SPELLSCROLL_WIDTH,
height = CONST_SPELLSCROLL_HEIGHT,
can_resize = false,
can_move = false,
can_move_children = false,
use_bottom_resizer = true,
use_right_resizer = true,
}
---@type dfframecontainer
local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer")
container:SetPoint("topleft", tabFrame, "topleft", 5, -5)
--replace this with a framework scrollframe
local scrollFrame = DF:CreateScrollBox(tabFrame, "$parentSpellScroll", refreshFunc, {}, CONST_SPELLSCROLL_WIDTH, CONST_SPELLSCROLL_HEIGHT, CONST_SPELLSCROLL_AMTLINES, CONST_SPELLSCROLL_LINEHEIGHT)
local scrollFrame = DF:CreateScrollBox(container, "$parentSpellScroll", refreshFunc, {}, CONST_SPELLSCROLL_WIDTH, CONST_SPELLSCROLL_HEIGHT, CONST_SPELLSCROLL_AMTLINES, CONST_SPELLSCROLL_LINEHEIGHT)
DF:ReskinSlider(scrollFrame)
DF:ApplyStandardBackdrop(scrollFrame)
scrollFrame:SetPoint("topleft", tabFrame, "topleft", 5, -5) --need to set the points
scrollFrame:EnableMouse(true)
scrollFrame:SetMovable(true)
container:RegisterChildForDrag(scrollFrame)
scrollFrame:SetPoint("topleft", container, "topleft", 0, 0) --need to set the points
--scrollFrame:EnableMouse(true)
--scrollFrame:SetMovable(true)
scrollFrame.DontHideChildrenOnPreRefresh = true
tabFrame.SpellScrollFrame = scrollFrame
spellsTab.SpellScrollFrame = scrollFrame
@@ -1307,6 +1322,7 @@ function spellsTab.CreateSpellScrollContainer(tabFrame)
--here need an api from the header frame to get the key to sort
print("key:", key)
--problem: -----
--pre process the data which may be used into the scroll