How to make a chat box like UI

Godot Version

Godot 4.2.2

Question

I am attempting to make a chat box(like a text message chat box) that scales properly with window resizing and the text for a “texting system”. I have attempted to do this at first by using a VBoxContainer and a Panel Container (containing a Label inside of a margin container) inside of a MarginContainer and trying to manually have a script swap between left-to-right and right-to-left on the margin containers based on whether it’s a “recieved” or “sent” message. It works fine to some degree, but to get this to work I either have to make a constant margin offset with the horizontal fill mode or have the shrink begin to ensure that it’s only on one side or the other. I also have tried just using control nodes and placing the MarginContainers containing all of the panels and text into there, but the scaling with anchor points seems to act a little off, in addition to the fact that it won’t allow me to make the scroll container fit any of the MarginContainers outside of the control node (which seems to be bound to the size of the scroll container). Is there a simpler way I could go about this? I want the box to have a minimum size, but also to be able to scale up according to window size + the text in the label (it should only be scaling longer if it can, like if I give it a line that is at its minimum size two lines long, scaling the window should allow it to become one line, but not have the panel expand beyond where the text ends)

To de-complicated the message label alignment you could set the size_flags_horizontal for each label to be either SIZE_SHRINK_BEGIN or SIZE_SHRINK_END for left/right respectively, instead of using a margin container and swapping with a script.

Without a scene graph it’s difficult to follow what’s happening, here’s what I’ve made trying to replicate your desired features.

The script on the root node is as follows

extends PanelContainer

func _on_line_edit_text_submitted(new_text: String) -> void:
	var new_label := Label.new()
	new_label.text = new_text
	new_label.size_flags_horizontal = Control.SIZE_SHRINK_END
	%Messages.add_child(new_label)
1 Like

Sorry, that’s my bad. I should’ve provided a scene graph in the original post. Below is kinda an example of what I was doing.

It’s extremely similar to what you showed in the image, but what I meant was if it was possible to have the chat bubbles resize based on the width of the window as its resized. As it is, the size will only work if a minimum size is specified within the label, and is what the size shown is. This seems fine on less wide screens, but what I was hoping to achieve was being able to have it so when the window widens, the elements will attempt to take up more space (like you can see how a message is three lines tall when what I would like is for it to take up all of the space it could within a proportional amount of the screen width) and be able to define its proportional bounds (wouldn’t want a message going all the way across the screen, as it would make it harder to differentiate whether a message is being sent or recieved. While I do predict that the most likely way will be programming the behavior myself, I am just wondering whether there is a simpler way.

have you changed the stretch mode in the project setting

Changing it to what? I messed around just now with a few of them and they seem to just make the entire ui scale proportional to the window size (including text font), which is not exactly good for more vertical aspect ratios (because everything shrinks, instead of just having the chat bubbles compress). Maybe I’m missing something?