Container's height depending on width

Geyser is an object oriented framework for creating, updating and organizing GUI elements within Mudlet.
Post Reply
vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Container's height depending on width

Post by vizman » Mon Feb 19, 2018 12:19 pm

F.e. i have such block of code:

Code: Select all

mapContainer = Geyser.Container:new({
	name = "mapContainer",
	x = 0,
	y = 0,
	width = "90%",
	height = width/2 --it doesnt work
})
How to make container that has width in % and height f.e. width/2. Width must be set in percentages and everytime window is resized, width/height must change too.

Jor'Mox
Posts: 1099
Joined: Wed Apr 03, 2013 2:19 am

Re: Container's height depending on width

Post by Jor'Mox » Mon Feb 19, 2018 2:26 pm

So, you have two problems there. The first is that both height and width are being declared in the same moment, so you can't use one to declare the other. The second is that you are trying to perform math on a string that doesn't easily convert to a number (i.e. the tonumber function returns a nil result from it).

To get around those problems, you first want to declare whatever you are going to use for your width before the declaration you are making, like so:

Code: Select all

local width = "90%"
mapContainer = Geyser.Container:new({
	name = "mapContainer",
	x = 0,
	y = 0,
	width = width,
	height = width/2 --it doesnt work
})
Then, you need to strip the number out from the string, perform the necessary math, and then put the percentage sign back, like so:

Code: Select all

local width = "90%"
mapContainer = Geyser.Container:new({
	name = "mapContainer",
	x = 0,
	y = 0,
	width = width,
	height = (tonumber(string.match(width,"%d+"))/2).."%"
})

vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Re: Container's height depending on width

Post by vizman » Mon Feb 19, 2018 3:59 pm

Thx, but it seems not working. Width is changing when resizing window but height is fixed to same value when changing f.e. only window horizontally.
Here is screen https://i.imgur.com/Ysgry0l.jpg
Ratio is much defferent than 1.5 used it this example. My goal is to keep ratio of container: f.e. 2:1, 1.5:1. etc.

Code: Select all

local width = "90%"

mapContainer = Geyser.Container:new({
	name = "mapContainer",
	x = 0,
	y = 0,
	width = width,
	height = (tonumber(string.match(width,"%d+"))/1.5).."%"
})
Anyway i have idea in my mind. I think height shouldnt be %, because it takes % of window height anyway. It should be value in px based on current width %.

Jor'Mox
Posts: 1099
Joined: Wed Apr 03, 2013 2:19 am

Re: Container's height depending on width

Post by Jor'Mox » Mon Feb 19, 2018 4:44 pm

Ah, I see, you are hoping for a fixed aspect ratio, while still scaling with screen size. That isn't something that Geyser is going to be able to do for you. To make that happen, you are going to need a script that handles the "sysWindowResize" event, and adjusts the window size as appropriate. A script like this would do that for a single label (created for example purposes).

Code: Select all

local labelName = "myLabel"
local maxWidth = "90%"
local maxHeight = "60%"
local aspectRatio = 1.5

function readjustWindowSize()
    local main_w, main_h = getMainWindowSize()
    local width, height = string.match(maxWidth,"%d+")*main_w/100, string.match(maxHeight,"%d+")*main_h/100
    
    if width/aspectRatio < height then
        height = width/aspectRatio
    end
    if height*aspectRatio < width then
        width = height*aspectRatio
    end
    
    resizeWindow(labelName,width,height)
end

registerAnonymousEventHandler("sysWindowResizeEvent", "readjustWindowSize")
As I see you are using Geyser containers, you are likely working with more than just a single GUI object, which means you will need to take care of the extra math to position and resize each such object within the function you are creating, rather than just resizing a single object, which will add a good bit of complexity, but should be workable.

vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Re: Container's height depending on width

Post by vizman » Mon Feb 19, 2018 6:08 pm

i see in documentation that:
resizeWindow(name,width,height)
Resizes a mini console, label, or floating User Windows.

So it wont resize containers i guess. Your solution works for label but not for whole container. A bit complicated now.
I guess there is no method for containers like myContainer:setHeight(x)?

vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Re: Container's height depending on width

Post by vizman » Mon Feb 19, 2018 6:19 pm

If you want, check for temporary code.

Code: Select all

--Map--
local labelName = "mapContainer"
local maxWidth = getMainWindowSize()
local maxHeight = maxWidth*0.7
local aspectRatio = 1.5

function readjustWindowSize()
    local main_w, main_h = getMainWindowSize()
    local width, height = string.match(maxWidth,"%d+")*main_w/100, string.match(maxHeight,"%d+")*main_h/100
    echo("hello")
		
    if width/aspectRatio < height then
        height = width/aspectRatio
    end
    if height*aspectRatio < width then
        width = height*aspectRatio
    end
    
    resizeWindow(labelName,width,height)
end

registerAnonymousEventHandler("sysWindowResizeEvent", "readjustWindowSize")

mapContainer = Geyser.Container:new({
	name = "mapContainer",
	x = 0,
	y = 0,
	width = "90%",
	height = "60%"
})


mapBorders = Geyser.Label:new({
  name = "mapBorders",
  x = 0, y = 0,
  width = "100%", height = "100%"
}, mapContainer)
mapBorders:setStyleSheet([[
	background-color: red;
	background-image : url(]]..ms_path..[[/images/background-01.png);
	border-style: solid;
	border-width: 21px;
	border-image: url(]]..ms_path..[[/images/border2.png) 21 no-fill round round;
]]);

--Stary Swiat--

mapStarySwiatContainer = Geyser.Container:new({
	name = "mapStarySwiatContainer",
	x = 0,
	y = 0,
	width = "100%",
	height = "100%"
}, mapContainer)

mapStarySwiat = Geyser.Label:new({
	name = "mapStarySwiat",
  x = 0, y = 0,
  width = "100%", height = "100%"
}, mapStarySwiatContainer)
mapStarySwiat:setStyleSheet([[
	background-color: transparent;
	border-image : url(]]..ms_path..[[/images/worldmap.png);
	margin: 83px 21px 21px 21px;
]]);

--/Stary Swiat--

mapCornerTL = Geyser.Label:new({
  x = 0, y = 0,
  width = 93, height = 92
}, mapContainer)
mapCornerTL:setStyleSheet([[
	background-color: transparent;
	background-image : url(]]..ms_path..[[/images/corner-tl.png);
	background-repeat: no-repeat;
]]);

mapCornerTR = Geyser.Label:new({
  x = -93, y = 0,
  width = 93, height = 92
}, mapContainer)
mapCornerTR:setStyleSheet([[
	background-color: transparent;
	background-image : url(]]..ms_path..[[/images/corner-tr.png);
	background-repeat: no-repeat;
]]);

mapCornerBL = Geyser.Label:new({
  x = 0, y = -92,
  width = 93, height = 92
}, mapContainer)
mapCornerBL:setStyleSheet([[
	background-color: transparent;
	background-image : url(]]..ms_path..[[/images/corner-bl.png);
	background-repeat: no-repeat;
]]);

mapCornerBR = Geyser.Label:new({
  x = -93, y = -92,
  width = 93, height = 92
}, mapContainer)
mapCornerBR:setStyleSheet([[
	background-color: transparent;
	background-image : url(]]..ms_path..[[/images/corner-br.png);
	background-repeat: no-repeat;
]]);

mapSubH = Geyser.Label:new({
  x = 0, y = 78,
  width = "100%", height = 7
}, mapContainer)
mapSubH:setStyleSheet([[
	background-color: transparent;
	background-image : url(]]..ms_path..[[/images/sub-h.png);
	border-left: 20px solid transparent;
	border-right: 20px solid transparent;
]]);

-- Buttons --

mapBtnExit = Geyser.Label:new({
	name = "mapBtnExit",
  x = -27, y = 0,
  width = 27, height = 27
}, mapContainer)
mapBtnExit:setStyleSheet([[
	QLabel{
		background-color: transparent;
		background-image : url(]]..ms_path..[[/images/btn-exit.png);
	}
	QLabel:hover{
		background-image : url(]]..ms_path..[[/images/btn-exit-hover.png);
	}
]]);

mapBtnStarySwiat = Geyser.Label:new({
	name = "mapBtnStarySwiat",
  x = 45, y = 31,
  width = 175, height = 35,
	fgColor = btn_font_color,
	fontSize = 10,
	message = [[<center>Stary Swiat</center>]]
}, mapContainer)
mapBtnStarySwiat:setStyleSheet([[
	QLabel{
		background-color: transparent;
		background-image : url(]]..ms_path..[[/images/btn-main.png);
		text-transform: uppercase;
		font-weight: 500;
	}
	QLabel:hover{
		background-image : url(]]..ms_path..[[/images/btn-main-hover.png);
	}
]]);

mapBtnIshtar = Geyser.Label:new({
	name = "mapBtnIshtar",
  x = 225, y = 31,
  width = 175, height = 35,
	fgColor = btn_font_color,
	fontSize = 10,
	message = [[<center>Ishtar</center>]]
}, mapContainer)
mapBtnIshtar:setStyleSheet([[
	QLabel{
		background-color: transparent;
		background-image : url(]]..ms_path..[[/images/btn-main.png);
		text-transform: uppercase;
		font-weight: 500;
	}
	QLabel:hover{
		background-image : url(]]..ms_path..[[/images/btn-main-hover.png);
	}
]]);

Jor'Mox
Posts: 1099
Joined: Wed Apr 03, 2013 2:19 am

Re: Container's height depending on width

Post by Jor'Mox » Mon Feb 19, 2018 7:17 pm

So, there is apparently actually a method for containers that you could use, the resize method. So once you have created mapContainer, you can use the sysWindowResize handling function to call mapContainer:resize(width, height)

Do note that I'm not in any way an expert with Geyser, as I use a different window management system. But looking at the code, it seems like it should work.

vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Re: Container's height depending on width

Post by vizman » Mon Feb 19, 2018 10:24 pm

Yep, this method works as it should! So later i will try combine it with sysWindowResizeEvent you suggested before and let you know if it works together. Big thanks.

vizman
Posts: 10
Joined: Fri Feb 09, 2018 8:48 pm

Re: Container's height depending on width

Post by vizman » Wed Feb 21, 2018 4:07 am

I have done it and it works perfectly.

Code: Select all

--Map--

local maxWidth, maxHeight = getMainWindowSize()
local mapContainerAspectRatio = 1.5
maxWidth = maxWidth*0.9
maxHeight = maxWidth/mapContainerAspectRatio


function resizeMapContainer()
	local getWidth, getHeight = getMainWindowSize()
	maxWidth = getWidth*0.9
	maxHeight = maxWidth/mapContainerAspectRatio
	
	if maxHeight > getHeight*0.9 then
		maxHeight = getHeight*0.9
		maxWidth = maxHeight*mapContainerAspectRatio
	end
	
	mapContainer:resize(maxWidth, maxHeight)
end

registerAnonymousEventHandler("sysWindowResizeEvent", "resizeMapContainer")

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests