diff --git a/tests/scene/test_control.h b/tests/scene/test_control.h index 3d7e389e0a70..a95caac51871 100644 --- a/tests/scene/test_control.h +++ b/tests/scene/test_control.h @@ -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); @@ -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