Help with Lua GUI programming

Hi i’ve been programming in Lua for a long time now but i’m finally stuck trying to get this to work, the problem is that when I make a new GUI element then set it’s position the next GUI element uses that as it’s position when it should inherit the position if it’s parent.

Here’s the main part of my code:


//If the pos is not set for each and every GUI element, the GUI element uses the last set pos for some reason -- Rework	
	
	//Create the background for the circle
	local circleBase = guiCreate('circleBase', '', 'filled_circle')
		circleBase.SetPos(SW / 3.75, SH / 2)
		circleBase.SetColor(Color(0, 0, 0, 225))
		circleBase.SetDegrees(degrees)
		circleBase.SetRadius(radius)
		circleBase.SetSides(sides)
	guiRun('circleBase')

	//Create the outline for the circle
	local circleOutline = guiCreate('circleOutline', 'circleBase', 'circle')
		circleOutline.SetColor(mainColor)
	guiRun('circleOutline')
	
	 //Draw 6 lines in the circle
	local lines = guiCreate('lines', 'circleBase', 'line_to_circle')
		lines.SetColor(mainColor)
		lines.SetPos(SW/2,SH/2)
	guiRun('lines')	
	
	//Draw the number of credits the player has in green
	local creditsWordBox = guiCreate('creditsWordBox', 'circleBase', 'centered_word_box')
		creditsWordBox.SetText('$'..ply:GetCredits())
		creditsWordBox.SetFont('counter_strike32')
		creditsWordBox.SetColor(Color(180, 230, 30, 255))
		creditsWordBox.SetBackColor(Color(0, 0, 0, 200))
	guiRun('creditsWordBox')

Here’s the GUI Lua file:


AddCSLuaFile()
include("draw_lib.lua")
include("math_lib.lua")

//GUI LUA files, all my GUI files can be found in "addons/(ADDON_NAME)/lua/autorun/client/gui"
include('gui/circle.lua')
include('gui/filled_circle.lua')
include('gui/centered_text.lua')
include('gui/centered_word_box.lua')
include('gui/text_at_segment.lua')
include('gui/filled_circle.lua')
include('gui/line_to_circle.lua')

local guiTable = {}

function guiCreate(name, childOf, _type)
	
	if name == childOf then print("Error, name is the same as childOf"); return end
	
	//No child set, so set everything to default
	if guiTable[childOf] == nil then
		
		guiTable[name] = {}
		//guiTable[name].name, guiTable[name].childOf = name, childOf
		guiTable[name]._type = _type
		guiTable[name].color, guiTable[name].backColor = Color(255, 255, 255, 255), Color(0, 0, 0, 255)
		guiTable[name].posX, guiTable[name].posY = ScrW() / 2, ScrH() / 2
		guiTable[name].sizeW, guiTable[name].sizeH = ScrW() / 2, ScrH() / 2
		guiTable[name].border = 8
		guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment = 360, 100, 16, 6
		guiTable[name].text, guiTable[name].font = 'Default', 'Default'
		guiTable[name].visible = true
	//Child was set so make everything based on it
	else

		guiTable[name] = guiTable[childOf]
		guiTable[name]._type = _type

	end

	//The GUI run function can't be in the return data as it acts like a callback, citation needed	
	return {GetColor = function()
							return guiTable[name].color
						end,
			SetColor = function(c)
							guiTable[name].color = c
						end,
			GetBackColor = function()
							return guiTable[name].backColor
						end,
			SetBackColor = function(c)
							guiTable[name].backColor = c
						end,
			GetPos = function()
							return guiTable[name].posX, guiTable[name].posY
						end,
			SetPos = function(x, y)
							guiTable[name].posX, guiTable[name].posY = x, y							
						end,
			GetSize = function()
							return guiTable[name].sizeW, guiTable[name].sizeH
						end,
			SetSize = function(w, h)
							guiTable[name].sizeW, guiTable[name].sizeH = w, h			
						end,
			GetBorder = function()
							return guiTable[name].border
						end,
			SetBorder = function(b)
							guiTable[name].border = b
						end,
			GetDegrees = function()
							return guiTable[name].degrees
						end,
			SetDegrees = function(d)
							guiTable[name].degrees = d
						end,
			GetRadius = function()
							return guiTable[name].radius
						end,
			SetRadius = function(r)
							guiTable[name].radius = r				
						end,
			GetSides = function()
							return guiTable[name].sides
						end,
			SetSides = function(s)
							guiTable[name].sides = s
						end,			
			GetSegment = function()
							return guiTable[name].segment
						end,
			SetSegment = function(s)
							guiTable[name].segment = s
						end,						
			GetText = function()
							return guiTable[name].text
						end,
			SetText = function(t)
							guiTable[name].text = t
						end,
			GetFont = function()
							return guiTable[name].font
						end,
			SetFont = function(f)
							guiTable[name].font = f
						end,	
			GetVisible = function()
							return guiTable[name].visible
						end,
			SetVisible = function(v)
							guiTable[name].visible = v
						end
			}
			
end

//I don't like having to do thing this way -- Rework
function guiRun(name)

	if guiTable[name]._type == 'circle' then
		circle				(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
		
	elseif guiTable[name]._type == 'filled_circle' then
		filled_circle		(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
		
	elseif guiTable[name]._type == 'centered_text' then
		centered_text		(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
		
	elseif guiTable[name]._type == 'centered_word_box' then
		centered_word_box	(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
		
	elseif guiTable[name]._type == 'text_at_segment' then
		text_at_segment		(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
	
	elseif guiTable[name]._type == 'line_to_circle' then
		line_to_circle		(guiTable[name].color, guiTable[name].backColor, guiTable[name].posX, guiTable[name].posY, guiTable[name].sizeW, guiTable[name].sizeH, guiTable[name].border, guiTable[name].degrees, guiTable[name].radius, guiTable[name].sides, guiTable[name].segment, guiTable[name].text, guiTable[name].font, guiTable[name].visible)
	
	end
	
end

Here’s the code for the GUI circle.lua file:


AddCSLuaFile()

//I think you can guess what these all do. Too many args for the functions -_-

function circle(color, backColor, posX, posY, sizeW, sizeH, border,  degrees, radius, sides, segments, text, font, visible)

	if !visible then return end
	
	surface.SetDrawColor(color)
		
	local angle
	local x
	local y
	
	for i = 0, degrees, degrees / sides do
		angle = i * math.pi / 180
		x = posX + radius * math.cos(angle)
		y = posY + radius * math.sin(angle)
		//Make sure that lastPtx and lastPty are not nil
		if i > 1 then
			surface.DrawLine(lastPtx, lastPty, x, y)
		end
		lastPtx = x
		lastPty = y
	end
	
end

Here’s the code for the GUI filled_circle.lua file:


AddCSLuaFile()

//I think you can guess what these all do. Too many args for the functions -_-

function filled_circle(color, backColor, posX, posY, sizeW, sizeH, border,  degrees, radius, sides, segments, text, font, visible)
	
	if !visible then return end
	
	surface.SetDrawColor(color)
	
	local angle
	local x
	local y
	local cir = {}
	
	for i = 0, degrees, degrees / sides do
		angle = i * math.pi / 180
		x = posX + radius * math.cos(angle)
		y = posY + radius * math.sin(angle)
		table.insert(cir, {x = x, y = y})
	end
	
	surface.DrawPoly(cir)
	
end

Here’s the code for the GUI line_to_circle.lua file:


AddCSLuaFile()

//I think you can guess what these all do. Too many args for the functions -_-
//Think of a better name.
function line_to_circle(color, backColor, posX, posY, sizeW, sizeH, border,  degrees, radius, sides, segments, text, font, visible)
	
	if !visible then return end
	
	surface.SetDrawColor(color)
	local offset = (degrees / segments) / 2
	local angle
	local x
	local y
	
	for i = offset, degrees + offset, degrees / segments do
		angle = i * math.pi / 180
		x = posX + radius * math.cos(angle)
		y = posY + radius * math.sin(angle)
		surface.DrawLine(posX, posY , x, y)
	end

end

Here’s the code for the GUI centered_word_box.lua file:


AddCSLuaFile()

//I think you can guess what these all do. Too many args for the functions -_-

function centered_word_box(color, backColor, posX, posY, sizeW, sizeH, border,  degrees, radius, sides, segments, text, font, visible)
	
	if !visible then return end
	
	surface.SetFont(font)
	local textWidth, textHeight = surface.GetTextSize(text)
	draw.WordBox(border, (posX - textWidth / 2) - border, (posY - textHeight / 2) - border, text, font, backColor, color)
	
end