0 votes

I'm trying to create a custom control like the one in the image below:

Basically, it is a rectangle positioned at viewport center with a label inside it. The label must be anchored at top left corner of the rectangle.
So, I've created a scene with an empty Control node and I've added a Label child node to it. I've attached a script to the control node which takes care to draw the rectangle and set its size. Here is the code:

extends Control


func _draw():
    draw_rect(Rect2(-100, -100, 200, 200), Color(0.0, 0.0, 0.0), false)

func _ready():
    set_size(Vector2(200, 200))

Just for sake of simplicity, in the code above the rectangle has a fixed size of 200x200, but in a real scenario it would have a dynamic size. My problem is the label node doesn't take in account the rectangle dimension, set with the set_size method, in calculating its anchorage. I guess I have to inform the label node about the real rectangle size... but how?

in Engine by (12 points)

1 Answer

0 votes

Assuming I understand your goal and your scene is structured like this:

+Control <-> Control.gd
+-Label

The this does what I think you're asking (plus some time based changes for visual):

extends Control

var time =0
export var box_size = Vector2(200,200) setget set_boxsize, boxsize

func set_boxsize(v):
    box_size = v
    set_size(box_size)
    if $Label:
        $Label.rect_position = Vector2(-box_size.x/2, -box_size.y/2)

func boxsize():
    return box_size

func _process(delta):
    time += delta
    set_boxsize( Vector2(200+(cos(time)*50),200+(sin(time)*50)))   

func _draw():
    draw_rect(Rect2(-box_size.x/2, -box_size.y/2, box_size.x, box_size.y), Color(0.0, 0.0, 0.0), false)

func _ready():
    set_boxsize(box_size)
by (16 points)
edited by

Yep, your solution works perfectly, but it is a way too specific. What about if the rectangle would have many child nodes with different anchoration settings? Doesn't exist a function to recalculate rect/transform of all child nodes?

I answered what you asked, there isn't a global child recalculation. You will have to write your own taking into account how you would want the scaling/sizing to affect each child.
In the original case is straightforward because it is anchored at the top left corner but other children could be positioned elsewhere and a global function would have to know how the child is to be repositioned:
- Is it a fixed offset from a side/corner/pivot of the parent?
- Is it positioned relative to another child?
- Are relative scales to be maintained
- Does the position and size of the child scale with the parent?

you might consider adapting the above code so that each the lastsize is recorded before boxsize is set and then use the rect_position / size of each child + some other variables stored with the child or parent to determine how each one should be repositioned and/or scaled

I'm not saying your answer isn't correct, at all. I wrote this super-simple example just to not have to provide all the context details.
I hoped that position settings choose for a child node (e.g. anchor at top left with 40px of margin) would have been automatically kept after a parent resize. Or at least, that a function would have been existed to automatically repos child nodes.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.