Well, one way to do it is to set up a lot of BoxContainers inside other BoxContainers, like this. With their size flags set to expand, they'll grow to fill available space. You'll have to change the outermost size and the font sizes on signal.
extends Node2D
var vb:VBoxContainer
var lab:Label
var butt:Array
var font:DynamicFont
func _ready() -> void:
font = DynamicFont.new()
font.font_data = load('res://DejaVuSans.ttf')
font.size = 30
vb = VBoxContainer.new()
vb.size_flags_vertical = Control.SIZE_EXPAND_FILL
vb.rect_size = Vector2(1024, 600)
add_child(vb)
lab = Label.new()
lab.set('custom_fonts/font', font)
lab.text = 'PCD ESCAPE'
lab.align = Label.ALIGN_CENTER
vb.add_child(lab)
var hb1 = HBoxContainer.new()
hb1.size_flags_vertical = Control.SIZE_EXPAND_FILL
hb1.size_flags_horizontal = Control.SIZE_EXPAND_FILL
vb.add_child(hb1)
var vb2 = []
for i in 3:
var b = VBoxContainer.new()
b.size_flags_horizontal = Control.SIZE_EXPAND_FILL
hb1.add_child(b)
vb2.append(b)
var vb3 = []
for i in 3:
var b := VBoxContainer.new()
b.size_flags_vertical = Control.SIZE_EXPAND_FILL
vb2[1].add_child(b)
b.set('custom_constants/separation', 20)
vb3.append(b)
for i in ['Start', 'Settings', 'Quit']:
var b := Button.new()
b.text = i
b.set('custom_fonts/font', font)
vb3[1].add_child(b)
butt.append(b)
get_tree().connect('screen_resized', self, 'resize_it')
func resize_it():
var sz = OS.window_size
vb.set_size(sz)
font.size = 30 * sz.y / 600
