return current dimensions of an object

Geyser is an object oriented framework for creating, updating and organizing GUI elements within Mudlet.
Post Reply
Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

return current dimensions of an object

Post by Caled »

I've been trying to write a function that will automatically create borders around a container.
To do this, I have to first store the information about the container itself into a table, and then create the table based on those values, and THEN run my function that will create the borders.

This is sort of working, but is less than ideal because it requires my entire gui to be within one table, and for the purpose of sharing scripts or using this function on different characters on different muds (or even sharing the function with the whole mudlet community) requiring it to use my namespace isn't really cutting it.

It also means that I must be really careful how I resize the gui element later; if I do it without changing the values in that table, or rerunning the avg.createBorders() function, I end up with misaligned borders that look ridiculous.

Is there a way to return the current position and dimensions of a container?
local posx, posy, sizex, sizey = my.container.name:get_constraints()
^ i.e. something like that?

It isn't in the Geyser documentation that I can see, but I figure it is worth asking because I keep missing stuff and attempting to reinvent the wheel.

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: return current dimensions of an object

Post by Caled »

Finally having discovered Geyser.display() I've been able to look at the tables Geyser creates, and that helped me understand the Geyser code, and now I've got:
Code: [show] | [select all] lua
-- Create borders for a container
function get_constraints(object)
	local x = assert( object.get_x)()
	local y = assert( object.get_y)()
	local w = assert( object.get_width)()
	local h = assert( object.get_height)()
	return x,y,w,h
end

function get_borders(object)
	local object = object
	local size = {}
	local pos = {}
	pos.x, pos.y, size.width, size.height = get_constraints(object)


	local col = object.bordercol or {r = 50, g = 50, b = 50, t = 255}
	local borderwidth = object.borderwidth or 3
	local sides = {left = {}, right = {}, top = {}, bottom = {}}

	--echo("\nx: " .. pos.x .. ", y: " .. pos.y .. ", width: " .. size.width .. ", height: " .. size.height)


	for side,v in pairs(sides) do
		local w = borderwidth
		local length, posx, posy, sizew, sizeh
		if side == "top" then
			length = size.width
			posx = 0
			posy = 0
			sizew = length
			sizeh = w
		elseif side == "bottom" then
			length = size.width
			posx = 0
			posy = size.height
			sizew = length
			sizeh = w
		elseif side == "left" then
			length = size.height
			posx = 0
			posy = 0
			sizew = w
			sizeh = length
		elseif side == "right" then
			length = size.height
			posx = size.width
			posy = 0
			sizew = w
			sizeh = length
		end
	--echo("\nSide: " .. side .. ",  x: " .. posx .. ", y: " .. posy .. ", width: " .. sizew .. ", height: " .. sizeh)
	sides[side] = { x = posx, y = posy, width = sizew, height = sizeh }
	end
	--display(sides)
	return sides
end
Which is getting there. Excuse the test echos and some of the naming is odd - once I get this working I'll go back and remove redundant stuff, and choose some better names than "sizew" etc.

What I have been unable to do though, is actually create the borders. I can use the values to create borders from another function, but I want to do:
Code: [show] | [select all] lua
function ci.layout.main.create()
	local cont = ci.layout.main
	local size = cont.size
	local pos = cont.pos

	-- Create the container
	ci.layout.main.container = Geyser.Container:new({ 
		name = cont.name,
		x = pos.x, 				y = pos.y,
		width = size.width, 	height = size.height
	}, layout)
	ci.layout.main.container:move(pos.x, pos.y)

	--Set the background
	local col = cont.background or {r = 80, g = 80, b = 80, t = 80}
	ci.layout.main.background = Geyser.Label:new({ 
		name = cont.name .. "_background",
		x = 0, 					y = 0,
		width = size.width, 	height = size.width,
	}, ci.layout.main.container)
	ci.layout.main.background:setColor(col.r, col.g, col.b, col.t)

        -- Add borders
        createBorders(ci.layout.main.container)
end
The entirety of the above is not particularly important, except to say that the main container is
ci.layout.main.container

and I want to do this:
createBorders(ci.layout.main.container)
and have borders added to the container. The problem is that the createBorders(object) function doesn't know that it is creating borders around 'co.layout.main.container'. It is figuring out the dimensions of the container element described by the local variable 'object', and when it knows what they are, it doesn't know where I want it to put them, or to what parent container I want them to be attached to.

I've succeeded in getting far enough to save myself a lot of hassle manually creating borders for every little thing in my gui, but if I could figure out this last step, the function might be useful to everyone else as well.

Ideas?

Widjet
Posts: 30
Joined: Thu Apr 22, 2010 1:43 am

Re: return current dimensions of an object

Post by Widjet »

I appreciate that you've probably figured this out by now, but I've been spending some lonely nights with Geyser lately, and I now know pretty well how it works.

I think the piece of the puzzle that you're missing is that every Geyser Container has a property, itself called 'container', that is a reference to the container that contains your object.

So your createBorders function could look something like this:
Code: [show] | [select all] lua
function createBorders(object)
    local c = object.container
    local border_top = Geyser.Label({x = ... etc.}, c)
    local border_right = ...
end

Post Reply