Open KirillGrigoriev opened 1 year ago
Anchors only work in «Anchors» layout mode, but controls creating with layout mode «Position» by default
That only applies to the inspector. There is no such limitation in code. Layout mode is an artificial restriction for the editor GUI, not an actual mode for a control.
they change size and position in moment of call, and don't handle any future control layout changes
That is indeed how anchoring works. Depending on the nature of the external changes you may need to re-apply anchors.
Let me explain by example. Let's created simple scene inherited by Control and add 2 Controls and 2 Labels inside this controls. Now setup «Layout Mode», «Anchor Preset», «Anchor Points», «Anchor Offsets» for given nodes (Control1, Label1, Control2, Label2): Controls act as expected when Windows (or parent node) is resized: Now, let's recreate this in C++ in GDExtension:
Control* control1 = memnew(Control);
control1->set_anchor(SIDE_BOTTOM, 1.0);
control1->set_anchor(SIDE_RIGHT, 0.5);
control1->set_offset(SIDE_BOTTOM, 0.0);
control1->set_offset(SIDE_LEFT, 0.0);
control1->set_offset(SIDE_RIGHT, 0.0);
control1->set_offset(SIDE_TOP, 0.0);
this->add_child(control1);
Label* label1 = memnew(Label);
label1->set_anchor_and_offset(SIDE_BOTTOM, 0.5, 0.0);
label1->set_anchor_and_offset(SIDE_LEFT, 0.5, 0.0);
label1->set_anchor_and_offset(SIDE_RIGHT, 0.5, 0.0);
label1->set_anchor_and_offset(SIDE_TOP, 0.5, 0.0);
label1->set_text("Hello, World!");
control1->add_child(label1);
Control* control2 = memnew(Control);
control2->set_anchor(SIDE_BOTTOM, 1.0);
control2->set_anchor(SIDE_LEFT, 0.5);
control2->set_anchor(SIDE_RIGHT, 1.0);
control1->set_offset(SIDE_BOTTOM, 0.0);
control1->set_offset(SIDE_LEFT, 0.0);
control1->set_offset(SIDE_RIGHT, 0.0);
control1->set_offset(SIDE_TOP, 0.0);
this->add_child(control2);
Label* label2 = memnew(Label);
label2->set_anchors_preset(Control::PRESET_CENTER);
label2->set_offset(SIDE_BOTTOM, 0.0);
label2->set_offset(SIDE_LEFT, 0.0);
label2->set_offset(SIDE_RIGHT, 0.0);
label2->set_offset(SIDE_TOP, 0.0);
label2->set_text("Hello, World!");
control2->add_child(label2);
Let's create another scene that extends our GDExtension Control class and now we see this: Now we see elements positioned incorrectly and handle resizing more unexpectedly.
Godot version
v4.1.2.stable.official [399c9dc39]
System information
Godot v4.1.2.stable - Windows 10.0.19045 - Vulkan (Compatibility) - NVIDIA GeForce GTX 650 (NVIDIA; 30.0.14.7430) - 13th Gen Intel(R) Core(TM) i5-13400 (16 Threads)
Issue description
Anchors only work in «Anchors» layout mode, but controls creating with layout mode «Position» by default, and method for changing layout_mode is not exported for GDExtension. In result, methods «set_anchors_preset», «set_offsets_preset», «set_anchors_and_offsets_preset», «set_anchor», «set_offset», «set_anchor_and_offset» don't work as supposed, they change size and position in moment of call, and don't handle any future control layout changes. In source file of Control (scene/gui/control.h) I found method «void _set_layout_mode(LayoutMode p_mode)», assume, one of previous methods should use this method internally or it should be exported, but this didn't happen. Also, seems like LayoutMode enumeration (values for changing layout_mode property) wasn't exported for GDScript, but it can be done by integer (like self.layout_mode = 1).
Steps to reproduce
Minimal reproduction project
N/A