Skip to content

Commit

Permalink
Layouter as alternative for LayoutHelpers (FAForever#3835)
Browse files Browse the repository at this point in the history
Provides an alternative approach to making UI elements by using a modern builder pattern.
  • Loading branch information
4z0t authored Jun 8, 2022
1 parent 1f38a3c commit 74596da
Show file tree
Hide file tree
Showing 2 changed files with 397 additions and 7 deletions.
389 changes: 389 additions & 0 deletions lua/maui/layouthelpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -474,4 +474,393 @@ end

function InvScaleNumber(number)
return math.floor(number * (1 / pixelScaleFactor))
end

--**********************************
--********* Layouter *************
--**********************************

local LayouterMetaTable = {}
LayouterMetaTable.__index = LayouterMetaTable

-- controls' mostly used methods

function LayouterMetaTable:Name(debugName)
self.c:SetName(debugName)
return self
end

function LayouterMetaTable:Disable()
self.c:Disable()
return self
end

function LayouterMetaTable:Hide()
self.c:Hide()
return self
end

function LayouterMetaTable:Color(color)
if self.c.SetSolidColor then
self.c:SetSolidColor(color)
elseif self.c.SetColor then
self.c:SetColor(color)
else
WARN(string.format("Unable to set color for control \"%s\"", self.c:GetName()))
end
return self
end

function LayouterMetaTable:DropShadow(bool)
self.c:SetDropShadow(bool)
return self
end

function LayouterMetaTable:Texture(texture, border)
self.c:SetTexture(texture, border)
return self
end

function LayouterMetaTable:EnableHitTest(recursive)
self.c:EnableHitTest(recursive)
return self
end

function LayouterMetaTable:DisableHitTest(recursive)
self.c:DisableHitTest(recursive)
return self
end

function LayouterMetaTable:NeedsFrameUpdate(bool)
self.c:SetNeedsFrameUpdate(bool)
return self
end

function LayouterMetaTable:Alpha(alpha, children)
self.c:SetAlpha(alpha, children)
return self
end

-- raw setting

function LayouterMetaTable:Left(left)
self.c.Left:Set(left)
return self
end

function LayouterMetaTable:Right(right)
self.c.Right:Set(right)
return self
end

function LayouterMetaTable:Top(top)
self.c.Top:Set(top)
return self
end

function LayouterMetaTable:Bottom(bottom)
self.c.Bottom:Set(bottom)
return self
end

function LayouterMetaTable:Width(width)
if iscallable(width) then
self.c.Width:SetFunction(width)
else
self.c.Width:SetValue(ScaleNumber(width))
end
return self
end

function LayouterMetaTable:Height(height)
if iscallable(height) then
self.c.Height:SetFunction(height)
else
self.c.Height:SetValue(ScaleNumber(height))
end
return self
end

-- Fill parent

function LayouterMetaTable:Fill(parent)
FillParent(self.c, parent)
return self
end

function LayouterMetaTable:FillFixedBorder(parent, offset)
FillParentFixedBorder(self.c, parent, offset)
return self
end

-- double-based positioning

function LayouterMetaTable:AtLeftTopIn(parent, leftOffset, topOffset)
AtLeftTopIn(self.c, parent, leftOffset, topOffset)
return self
end

function LayouterMetaTable:AtRightBottomIn(parent, rightOffset, bottomOffset)
AtRightBottomIn(self.c, parent, rightOffset, bottomOffset)
return self
end

function LayouterMetaTable:AtLeftBottomIn(parent, leftOffset, bottomOffset)
AtLeftBottomIn(self.c, parent, leftOffset, bottomOffset)
return self
end

function LayouterMetaTable:AtRightTopIn(parent, rightOffset, topOffset)
AtRightTopIn(self.c, parent, rightOffset, topOffset)
return self
end

-- centered out of parent

function LayouterMetaTable:CenteredLeftOf(parent, offset)
CenteredLeftOf(self.c, parent, offset)
return self
end

function LayouterMetaTable:CenteredRightOf(parent, offset)
CenteredRightOf(self.c, parent, offset)
return self
end

function LayouterMetaTable:CenteredAbove(parent, offset)
CenteredAbove(self.c, parent, offset)
return self
end

function LayouterMetaTable:CenteredBelow(parent, offset)
CenteredBelow(self.c, parent, offset)
return self
end

-- centered--

function LayouterMetaTable:AtHorizontalCenterIn(parent, offset)
AtHorizontalCenterIn(self.c, parent, offset)
return self
end

function LayouterMetaTable:AtVerticalCenterIn(parent, offset)
AtVerticalCenterIn(self.c, parent, offset)
return self
end

function LayouterMetaTable:AtCenterIn(parent, vertOffset, horzOffset)
AtCenterIn(self.c, parent, vertOffset, horzOffset)
return self
end

-- single-in positioning

function LayouterMetaTable:AtLeftIn(parent, offset)
AtLeftIn(self.c, parent, offset)
return self
end

function LayouterMetaTable:AtRightIn(parent, offset)
AtRightIn(self.c, parent, offset)
return self
end

function LayouterMetaTable:AtTopIn(parent, offset)
AtTopIn(self.c, parent, offset)
return self
end

function LayouterMetaTable:AtBottomIn(parent, offset)
AtBottomIn(self.c, parent, offset)
return self
end

-- center-in positioning

function LayouterMetaTable:AtLeftCenterIn(parent, offset, verticalOffset)
AtLeftIn(self.c, parent, offset)
AtVerticalCenterIn(self.c, parent, verticalOffset)
return self
end

function LayouterMetaTable:AtRightCenterIn(parent, offset, verticalOffset)
AtRightIn(self.c, parent, offset)
AtVerticalCenterIn(self.c, parent, verticalOffset)
return self
end

function LayouterMetaTable:AtTopCenterIn(parent, offset, horizonalOffset)
AtTopIn(self.c, parent, offset)
AtHorizontalCenterIn(self.c, parent, horizonalOffset)
return self
end

function LayouterMetaTable:AtBottomCenterIn(parent, offset, horizonalOffset)
AtBottomIn(self.c, parent, offset)
AtHorizontalCenterIn(self.c, parent, horizonalOffset)
return self
end

-- center-in positioning

function LayouterMetaTable:AtLeftCenterIn(parent, offset, verticalOffset)
AtLeftIn(self.c, parent, offset)
AtVerticalCenterIn(self.c, parent, verticalOffset)
return self
end

function LayouterMetaTable:AtRightCenterIn(parent, offset, verticalOffset)
AtRightIn(self.c, parent, offset)
AtVerticalCenterIn(self.c, parent, verticalOffset)
return self
end

function LayouterMetaTable:AtTopCenterIn(parent, offset, horizonalOffset)
AtTopIn(self.c, parent, offset)
AtHorizontalCenterIn(self.c, parent, horizonalOffset)
return self
end

function LayouterMetaTable:AtBottomCenterIn(parent, offset, horizonalOffset)
AtBottomIn(self.c, parent, offset)
AtHorizontalCenterIn(self.c, parent, horizonalOffset)
return self
end

-- out-of positioning

function LayouterMetaTable:Below(parent, offset)
Below(self.c, parent, offset)
return self
end

function LayouterMetaTable:Above(parent, offset)
Above(self.c, parent, offset)
return self
end

function LayouterMetaTable:RightOf(parent, offset)
RightOf(self.c, parent, offset)
return self
end

function LayouterMetaTable:LeftOf(parent, offset)
LeftOf(self.c, parent, offset)
return self
end

-- depth--

function LayouterMetaTable:Over(parent, depth)
DepthOverParent(self.c, parent, depth)
return self
end

function LayouterMetaTable:Under(parent, depth)
DepthUnderParent(self.c, parent, depth)
return self
end

-- anchor--

function LayouterMetaTable:AnchorToTop(parent, offset)
AnchorToTop(self.c, parent, offset)
return self
end

function LayouterMetaTable:AnchorToLeft(parent, offset)
AnchorToLeft(self.c, parent, offset)
return self
end

function LayouterMetaTable:AnchorToRight(parent, offset)
AnchorToRight(self.c, parent, offset)
return self
end

function LayouterMetaTable:AnchorToBottom(parent, offset)
AnchorToBottom(self.c, parent, offset)
return self
end


-- resets control's properties to default

function LayouterMetaTable:ResetLeft()
ResetLeft(self.c)
return self
end

function LayouterMetaTable:ResetRight()
ResetRight(self.c)
return self
end

function LayouterMetaTable:ResetBottom()
ResetBottom(self.c)
return self
end

function LayouterMetaTable:ResetHeight()
ResetHeight(self.c)
return self
end

function LayouterMetaTable:ResetTop()
ResetTop(self.c)
return self
end

function LayouterMetaTable:ResetWidth()
ResetWidth(self.c)
return self
end

-- get control --

function LayouterMetaTable:Get()
return self.c
end

-- calculates control's Properties to determine its layout completion
-- and returns it
-- remember, if parent has incomplete layout it will warn you anyway

function LayouterMetaTable:End()
if not pcall(self.c.Top) or not pcall(self.c.Bottom) or not pcall(self.c.Height) then
WARN(string.format("Incorrect layout for \"%s\" Top-Height-Bottom", self.c:GetName()))
WARN(debug.traceback())
end

if not pcall(self.c.Left) or not pcall(self.c.Right) or not pcall(self.c.Width) then
WARN(string.format("Incorrect layout for \"%s\" Left-Width-Right", self.c:GetName()))
WARN(debug.traceback())
end

return self.c
end

function LayouterMetaTable:__newindex(key, value)
error("attempt to set new index for a Layouter object")
end

function LayoutFor(control)
local result = {
c = control
}
setmetatable(result, LayouterMetaTable)
return result
end

local layouter = {
c = false
}
setmetatable(layouter, LayouterMetaTable)

-- use if you don't cache layouter object

function ReusedLayoutFor(control)
layouter.c = control or false
return layouter
end
Loading

0 comments on commit 74596da

Please sign in to comment.