Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for control to test anchoring and minimum size #98757

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 209 additions & 1 deletion tests/scene/test_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

namespace TestControl {

TEST_CASE("[SceneTree][Control]") {
TEST_CASE("[SceneTree][Control] Transforms") {
SUBCASE("[Control][Global Transform] Global Transform should be accessible while not in SceneTree.") { // GH-79453
Control *test_node = memnew(Control);
Control *test_child = memnew(Control);
Expand All @@ -61,6 +61,214 @@ TEST_CASE("[SceneTree][Control]") {
}
}

TEST_CASE("[SceneTree][Control] Anchoring") {
Control *test_control = memnew(Control);
Control *test_child = memnew(Control);
test_control->add_child(test_child);
test_control->set_size(Size2(2, 2));
Window *root = SceneTree::get_singleton()->get_root();
root->add_child(test_control);

SUBCASE("Anchoring without offsets") {
test_child->set_anchor(SIDE_RIGHT, 0.75);
test_child->set_anchor(SIDE_BOTTOM, 0.1);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(1.5, 0.2)),
"With no LEFT or TOP anchors, positive RIGHT and BOTTOM anchors should be proportional to the size.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(0, 0)),
"With positive RIGHT and BOTTOM anchors set and no LEFT or TOP anchors, the position should not change.");

test_child->set_anchor(SIDE_LEFT, 0.5);
test_child->set_anchor(SIDE_TOP, 0.01);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(0.5, 0.18)),
"With all anchors set, the size should fit between all four anchors.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(1, 0.02)),
"With all anchors set, the LEFT and TOP anchors should proportional to the position.");
}

SUBCASE("Anchoring with offsets") {
test_child->set_offset(SIDE_RIGHT, 0.33);
test_child->set_offset(SIDE_BOTTOM, 0.2);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(0.33, 0.2)),
"With no anchors or LEFT or TOP offsets set, the RIGHT and BOTTOM offsets should be equal to size.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(0, 0)),
"With only positive RIGHT and BOTTOM offsets set, the position should not change.");

test_child->set_offset(SIDE_LEFT, 0.1);
test_child->set_offset(SIDE_TOP, 0.05);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(0.23, 0.15)),
"With no anchors set, the size should fit between all four offsets.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(0.1, 0.05)),
"With no anchors set, the LEFT and TOP offsets should be equal to the position.");

test_child->set_anchor(SIDE_RIGHT, 0.5);
test_child->set_anchor(SIDE_BOTTOM, 0.3);
test_child->set_anchor(SIDE_LEFT, 0.2);
test_child->set_anchor(SIDE_TOP, 0.1);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
"Anchors adjust size first then it is affected by offsets.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(0.5, 0.25)),
"Anchors adjust positions first then it is affected by offsets.");

test_child->set_offset(SIDE_RIGHT, -0.1);
test_child->set_offset(SIDE_BOTTOM, -0.01);
test_child->set_offset(SIDE_LEFT, -0.33);
test_child->set_offset(SIDE_TOP, -0.16);
CHECK_MESSAGE(
test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
"Keeping offset distance equal when changing offsets, keeps size equal.");
CHECK_MESSAGE(
test_child->get_position().is_equal_approx(Vector2(0.07, 0.04)),
"Negative offsets move position in top left direction.");
}

SUBCASE("Anchoring is preserved on parent size changed") {
test_child->set_offset(SIDE_RIGHT, -0.05);
test_child->set_offset(SIDE_BOTTOM, 0.1);
test_child->set_offset(SIDE_LEFT, 0.05);
test_child->set_offset(SIDE_TOP, 0.1);
test_child->set_anchor(SIDE_RIGHT, 0.3);
test_child->set_anchor(SIDE_BOTTOM, 0.85);
test_child->set_anchor(SIDE_LEFT, 0.2);
test_child->set_anchor(SIDE_TOP, 0.55);
CHECK(test_child->get_rect().is_equal_approx(
Rect2(Vector2(0.45, 1.2), Size2(0.1, 0.6))));

test_control->set_size(Size2(4, 1));
CHECK(test_child->get_rect().is_equal_approx(
Rect2(Vector2(0.85, 0.65), Size2(0.3, 0.3))));
}

memdelete(test_child);
memdelete(test_control);
}

TEST_CASE("[SceneTree][Control] Custom minimum size") {
Control *test_control = memnew(Control);
test_control->set_custom_minimum_size(Size2(4, 2));
Window *root = SceneTree::get_singleton()->get_root();
root->add_child(test_control);
CHECK_MESSAGE(
test_control->get_size().is_equal_approx(Vector2(4, 2)),
"Size increases to match custom minimum size.");

test_control->set_size(Size2(5, 4));
CHECK_MESSAGE(
test_control->get_size().is_equal_approx(Vector2(5, 4)),
"Size does not change if above custom minimum size.");

test_control->set_size(Size2(1, 1));
CHECK_MESSAGE(
test_control->get_size().is_equal_approx(Vector2(4, 2)),
"Size matches minimum size if set below custom minimum size.");

test_control->set_size(Size2(3, 3));
CHECK_MESSAGE(
test_control->get_size().is_equal_approx(Vector2(4, 3)),
"Adjusts only x axis size if x is below custom minimum size.");

test_control->set_size(Size2(10, 0.1));
CHECK_MESSAGE(
test_control->get_size().is_equal_approx(Vector2(10, 2)),
"Adjusts only y axis size if y is below custom minimum size.");

memdelete(test_control);
}

TEST_CASE("[SceneTree][Control] Grow direction") {
Control *test_control = memnew(Control);
test_control->set_size(Size2(1, 1));
Window *root = SceneTree::get_singleton()->get_root();
root->add_child(test_control);

SUBCASE("Defaults") {
CHECK(test_control->get_h_grow_direction() == Control::GROW_DIRECTION_END);
CHECK(test_control->get_v_grow_direction() == Control::GROW_DIRECTION_END);
}

SIGNAL_WATCH(test_control, SNAME("minimum_size_changed"))
Array signal_args;
signal_args.push_back(Array());

SUBCASE("Horizontal grow direction begin") {
test_control->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
test_control->set_custom_minimum_size(Size2(2, 2));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args)
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(-1, 0), Size2(2, 2))),
"Expand leftwards.");
}

SUBCASE("Vertical grow direction begin") {
test_control->set_v_grow_direction(Control::GROW_DIRECTION_BEGIN);
test_control->set_custom_minimum_size(Size2(4, 3));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args);
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(0, -2), Size2(4, 3))),
"Expand upwards.");
}

SUBCASE("Horizontal grow direction end") {
test_control->set_h_grow_direction(Control::GROW_DIRECTION_END);
test_control->set_custom_minimum_size(Size2(5, 3));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args);
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(0, 0), Size2(5, 3))),
"Expand rightwards.");
}

SUBCASE("Vertical grow direction end") {
test_control->set_v_grow_direction(Control::GROW_DIRECTION_END);
test_control->set_custom_minimum_size(Size2(4, 4));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args);
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(0, 0), Size2(4, 4))),
"Expand downwards.");
;
}

SUBCASE("Horizontal grow direction both") {
test_control->set_h_grow_direction(Control::GROW_DIRECTION_BOTH);
test_control->set_custom_minimum_size(Size2(2, 4));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args);
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(-0.5, 0), Size2(2, 4))),
"Expand equally leftwards and rightwards.");
}

SUBCASE("Vertical grow direction both") {
test_control->set_v_grow_direction(Control::GROW_DIRECTION_BOTH);
test_control->set_custom_minimum_size(Size2(6, 3));
SceneTree::get_singleton()->process(0);
SIGNAL_CHECK("minimum_size_changed", signal_args);
CHECK_MESSAGE(
test_control->get_rect().is_equal_approx(
Rect2(Vector2(0, -1), Size2(6, 3))),
"Expand equally upwards and downwards.");
}

memdelete(test_control);
}

} // namespace TestControl

#endif // TEST_CONTROL_H