How to stick a GUI element top left

Thanks for the quick answer @sven.
It is in fact totally possible if you want your element to resize as your screen changes size.
But what if that element should not be resized ?

where is the adjust references parameter?

In the root node of your gui.

I see, sorry missed that! :slight_smile: Let me give it a try…

1 Like

ok thanks.

You need to apply the inverse of the GUI scale to the node to make it not resize as the screen scale.

1 / math.min(render.get_window_width() / render.get_width(), render.get_window_height() / render.get_height())

Also you should have a root node which has the anchor set with custom size of 0,0,0 and ideally with a texture of a 1px transparent pixel with same texture as your other GUI elements where you put children nodes below.

1 Like

I was able to do it through some GUI script logic, is this what you wanted?

gui_alignment_example.zip (203.8 KB)

1 Like

thats good, but too complicated

Hi guys. So, I have sort of a custom solution for precise GUI and game object layouts (and black bar letterboxing and GUI <-> GO coordinate conversion). It’s part of the set of modules I’m going to release soon. I’m still writing docs and examples for them, though.

6 Likes

I’m curious about this use case. Why wouldn’t you want the UI element to scale with the size of the screen?

1 Like

I’ve used it when keeping some pixel font text at the corner of the screen. It’s also useful for pixel icons. Like level editor buttons. Some games you don’t need the UI to resize you want as much space as possible for the game.

1 Like

Actually, I’ve had situations when I wanted the node to scale differently from the way Defold normally scales nodes (fit/zoom/stretch). For example, 90% of our game scales nodes based soley on the X axis scale (window_width / design_width).

1 Like

I’ve seen that broken in many desktop games on High-DPI screens, where the text becomes too small to read. A good strategy there would be to compute the scale as you would normally, but then round it off to the nearest integer. Defold obviously doesn’t support that, but you will be able to do that with my layout module. Starts working frantically on docs.

4 Likes

Fair points @Pkeod and @dapetcu21!

1 Like

Thanks to @sven and @Pkeod for their answer !
And to reply to @britzl I’m currently working on a pixel perfect desktop game where resizing the screen results in showing more of the game world. My ui elements must be displayed always at the same scale like the world.
But it may become a problem when screen resolutions will be too large… So right now I’m really just trying different stuffs.
@dapetcu21 can’t wait to see your extension !

@ChienBleu You can try the same approach when calculating your projection in the render script. For example, in the default render script, in fixed_fit_projection, you can do zoom = math.max(1, math.floor(zoom + 0.5)) and you’ll have the desired effect.

Would you mind explaining just a bit more what would this achieve for the rendering of the game ?
Right now I’m using rendercam but I don’t mind returning to a custom render script as long as it achieves a nice solution.

It would mean that as you increase the size of the screen it would start showing more of the game world, but if you start increasing even more in both directions, at a certain point the pixel size suddenly jumps from 1x1 to 2x2, then from 2x2 to 3x3, etc.

2 Likes

Exactly what I’m looking for !
I will try that as soon as possible !

1 Like

I like this example doing it all in the gui_script without needing to edit the render, here is it simplified and improve to work with all scales assuming the root scaler node starts a 1 (then can child anything else at different scales below it)

local function update_node(self)
	gui.set_scale(self.scaled_node, vmath.vector3(1 / math.min(self.screen_width / self.width, self.screen_height / self.height), 1 / math.min(self.screen_width / self.width, self.screen_height / self.height), 1 / math.min(self.screen_width / self.width, self.screen_height / self.height)))
end


local function window_callback(self, event, data)
	if event == window.WINDOW_EVENT_RESIZED then
		self.screen_width = data.width
		self.screen_height = data.height

		update_node(self)
	end
end

function init(self)
	self.scaled_node = gui.get_node("scaled_node")
	self.node_scale = gui.get_scale(self.scaled_node)
	self.screen_width = gui.get_width()
	self.screen_height = gui.get_height()
	self.width = self.screen_width
	self.height = self.screen_height

	update_node(self)
	
	window.set_listener(window_callback)
end

For anyone searching, this is useful to make things scale 1:1 no matter how you scale the window. So if you want an FPS counter at the corner of your screen or something you can use a tiny pixel font and it will look good no matter the windo scale.

2 Likes