Path: blob/master/tests/scene/test_box_container.cpp
59209 views
/**************************************************************************/1/* test_box_container.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "tests/test_macros.h"3132TEST_FORCE_LINK(test_box_container)3334#include "scene/gui/box_container.h"35#include "scene/gui/control.h"36#include "scene/main/scene_tree.h"37#include "scene/main/window.h"3839namespace TestBoxContainer {4041TEST_CASE("[SceneTree][BoxContainer] HBoxContainer") {42HBoxContainer *hbox_container = memnew(HBoxContainer);43Window *root = SceneTree::get_singleton()->get_root();44root->add_child(hbox_container);4546hbox_container->set_size(Size2(100, 100));47SceneTree::get_singleton()->process(0);4849SUBCASE("Default behavior") {50Control *child_control = memnew(Control);51hbox_container->add_child(child_control);52SceneTree::get_singleton()->process(0);5354CHECK_MESSAGE(55hbox_container->get_alignment() == BoxContainer::ALIGNMENT_BEGIN,56"HBoxContainer alignment is set to ALIGNMENT_BEGIN by default.");5758CHECK_MESSAGE(59!hbox_container->is_vertical(),60"HBoxContainer orientation is horizontal.");6162CHECK_MESSAGE(63child_control->get_position().is_equal_approx(Point2(0, 0)),64"Child control is aligned to the left in ALIGNMENT_BEGIN mode.");6566CHECK_MESSAGE(67child_control->get_h_size_flags() == Control::SIZE_FILL,68"Child control horizontal size flags are set to SIZE_FILL by default.");6970CHECK_MESSAGE(71child_control->get_v_size_flags() == Control::SIZE_FILL,72"Child control vertical size flags are set to SIZE_FILL by default.");7374CHECK_MESSAGE(75child_control->get_size().is_equal_approx(Size2(0, 100)),76"Child control takes up minimum horizontal space and matches container height by default.");7778memdelete(child_control);79}8081SUBCASE("Child Horizontal Size Flags") {82Control *child_control = memnew(Control);83hbox_container->add_child(child_control);84child_control->set_custom_minimum_size(Size2(20, 20));85SceneTree::get_singleton()->process(0);8687CHECK_MESSAGE(88child_control->get_position().is_equal_approx(Point2(0, 0)),89"Child control is aligned to the left by default with SIZE_FILL.");9091child_control->set_h_size_flags(Control::SIZE_SHRINK_BEGIN);92SceneTree::get_singleton()->process(0);9394CHECK_MESSAGE(95child_control->get_position().is_equal_approx(Point2(0, 0)),96"Child control is aligned to the left of in SIZE_SHRINK_BEGIN horizontal size flag mode.");9798child_control->set_h_size_flags(Control::SIZE_SHRINK_CENTER);99SceneTree::get_singleton()->process(0);100101CHECK_MESSAGE(102child_control->get_position().is_equal_approx(Point2(0, 0)),103"Child control is aligned to the left of in SIZE_SHRINK_CENTER horizontal size flag mode.");104105child_control->set_h_size_flags(Control::SIZE_SHRINK_END);106SceneTree::get_singleton()->process(0);107108CHECK_MESSAGE(109child_control->get_position().is_equal_approx(Point2(0, 0)),110"Child control is aligned to the left of in SIZE_SHRINK_END horizontal size flag mode.");111112child_control->set_h_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_BEGIN);113SceneTree::get_singleton()->process(0);114115CHECK_MESSAGE(116child_control->get_position().is_equal_approx(Point2(0, 0)),117"Child control is aligned to the left in SIZE_EXPAND | SIZE_SHRINK_BEGIN horizontal size flag mode.");118119child_control->set_h_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_CENTER);120SceneTree::get_singleton()->process(0);121122CHECK_MESSAGE(123child_control->get_position().is_equal_approx(Point2(40, 0)),124"Child control is aligned to the center in SIZE_EXPAND | SIZE_SHRINK_CENTER horizontal size flag mode.");125126child_control->set_h_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_END);127SceneTree::get_singleton()->process(0);128129CHECK_MESSAGE(130child_control->get_position().is_equal_approx(Point2(80, 0)),131"Child control is aligned to the right in SIZE_EXPAND | SIZE_SHRINK_END horizontal size flag mode.");132133memdelete(child_control);134}135136SUBCASE("Child Vertical Size Flags") {137Control *child_control = memnew(Control);138hbox_container->add_child(child_control);139SceneTree::get_singleton()->process(0);140141CHECK_MESSAGE(142child_control->get_position().is_equal_approx(Point2(0, 0)),143"Child control is aligned to the top by default with SIZE_FILL.");144145child_control->set_v_size_flags(Control::SIZE_SHRINK_BEGIN);146SceneTree::get_singleton()->process(0);147148CHECK_MESSAGE(149child_control->get_position().is_equal_approx(Point2(0, 0)),150"Child control is aligned to the top of in SIZE_SHRINK_BEGIN vertical size flag mode.");151152child_control->set_v_size_flags(Control::SIZE_SHRINK_CENTER);153SceneTree::get_singleton()->process(0);154155CHECK_MESSAGE(156child_control->get_position().is_equal_approx(Point2(0, 50)),157"Child control is aligned to the center of in SIZE_SHRINK_CENTER vertical size flag mode.");158159child_control->set_v_size_flags(Control::SIZE_SHRINK_END);160SceneTree::get_singleton()->process(0);161162CHECK_MESSAGE(163child_control->get_position().is_equal_approx(Point2(0, 100)),164"Child control is aligned to the bottom of in SIZE_SHRINK_END vertical size flag mode.");165166memdelete(child_control);167}168169SUBCASE("Child Alignment") {170Control *child_control = memnew(Control);171hbox_container->add_child(child_control);172SceneTree::get_singleton()->process(0);173174CHECK_MESSAGE(175child_control->get_position().is_equal_approx(Point2(0, 0)),176"Child control is aligned to the left in ALIGNMENT_BEGIN mode by default.");177178hbox_container->set_alignment(BoxContainer::ALIGNMENT_CENTER);179SceneTree::get_singleton()->process(0);180181CHECK_MESSAGE(182child_control->get_position().is_equal_approx(Point2(50, 0)),183"Child control is aligned to the center in ALIGNMENT_CENTER mode.");184185hbox_container->set_alignment(BoxContainer::ALIGNMENT_END);186SceneTree::get_singleton()->process(0);187188CHECK_MESSAGE(189child_control->get_position().is_equal_approx(Point2(100, 0)),190"Child control is aligned to the right in ALIGNMENT_END mode.");191192memdelete(child_control);193}194195SUBCASE("Child Alignment RTL") {196Control *child_control = memnew(Control);197hbox_container->add_child(child_control);198hbox_container->set_layout_direction(Control::LAYOUT_DIRECTION_RTL);199SceneTree::get_singleton()->process(0);200201CHECK_MESSAGE(202child_control->get_position().is_equal_approx(Point2(100, 0)),203"Child control is aligned to the right in RTL ALIGNMENT_BEGIN mode by default.");204205hbox_container->set_alignment(BoxContainer::ALIGNMENT_CENTER);206SceneTree::get_singleton()->process(0);207208CHECK_MESSAGE(209child_control->get_position().is_equal_approx(Point2(50, 0)),210"Child control is aligned to the center in RTL ALIGNMENT_CENTER mode.");211212hbox_container->set_alignment(BoxContainer::ALIGNMENT_END);213SceneTree::get_singleton()->process(0);214215CHECK_MESSAGE(216child_control->get_position().is_equal_approx(Point2(0, 0)),217"Child control is aligned to the right in RTL ALIGNMENT_END mode.");218219memdelete(child_control);220}221222SUBCASE("Child Separation") {223Control *child_control_1 = memnew(Control);224Control *child_control_2 = memnew(Control);225hbox_container->add_child(child_control_1);226hbox_container->add_child(child_control_2);227228hbox_container->add_theme_constant_override("separation", 10);229SceneTree::get_singleton()->process(0);230231CHECK_MESSAGE(232child_control_2->get_position().is_equal_approx(Point2(10, 0)),233"Child controls are separated by the specified separation value.");234235memdelete(child_control_1);236memdelete(child_control_2);237}238239SUBCASE("Spacers") {240Control *child_control_1 = memnew(Control);241Control *child_control_2 = memnew(Control);242hbox_container->add_child(child_control_1);243hbox_container->add_spacer();244hbox_container->add_child(child_control_2);245hbox_container->add_theme_constant_override("separation", 0);246SceneTree::get_singleton()->process(0);247248CHECK_MESSAGE(249child_control_2->get_position().is_equal_approx(Point2(100, 0)),250"Spacer pushes child controls apart.");251252memdelete(child_control_1);253memdelete(child_control_2);254}255256SUBCASE("Expanding children") {257Control *child_control_1 = memnew(Control);258Control *child_control_2 = memnew(Control);259hbox_container->add_child(child_control_1);260hbox_container->add_child(child_control_2);261hbox_container->add_theme_constant_override("separation", 0);262263child_control_1->set_h_size_flags(Control::SIZE_EXPAND_FILL);264SceneTree::get_singleton()->process(0);265266CHECK_MESSAGE(267child_control_1->get_size().is_equal_approx(Size2(100, 100)),268"One child control expands to fill available space.");269270CHECK_MESSAGE(271child_control_2->get_size().is_equal_approx(Size2(0, 100)),272"The non-expanding child control remains at minimum size.");273274CHECK_MESSAGE(275child_control_1->get_position().is_equal_approx(Point2(0, 0)),276"Expanding child control is aligned to the left.");277278CHECK_MESSAGE(279child_control_2->get_position().is_equal_approx(Point2(100, 0)),280"Non-expanding child control is positioned after the expanding child control.");281282child_control_2->set_custom_minimum_size(Size2(20, 0));283SceneTree::get_singleton()->process(0);284285CHECK_MESSAGE(286child_control_1->get_size().is_equal_approx(Size2(80, 100)),287"Expanding child control shrinks to accommodate the custom minimum size of the other child.");288289CHECK_MESSAGE(290child_control_2->get_size().is_equal_approx(Size2(20, 100)),291"The non-expanding child control respects its custom minimum size.");292293CHECK_MESSAGE(294child_control_1->get_position().is_equal_approx(Point2(0, 0)),295"Expanding child control is aligned to the left.");296297CHECK_MESSAGE(298child_control_2->get_position().is_equal_approx(Point2(80, 0)),299"Non-expanding child control is positioned after the expanding child control.");300301child_control_2->set_h_size_flags(Control::SIZE_EXPAND_FILL);302SceneTree::get_singleton()->process(0);303304CHECK_MESSAGE(305child_control_1->get_size().is_equal_approx(Size2(50, 100)),306"Both child controls expand equally to fill available space.");307308CHECK_MESSAGE(309child_control_2->get_size().is_equal_approx(Size2(50, 100)),310"Both child controls expand equally to fill available space.");311312CHECK_MESSAGE(313child_control_1->get_position().is_equal_approx(Point2(0, 0)),314"First expanding child control is aligned to the left.");315316CHECK_MESSAGE(317child_control_2->get_position().is_equal_approx(Point2(50, 0)),318"Second expanding child control is positioned after the first expanding child control.");319320child_control_2->set_stretch_ratio(3);321SceneTree::get_singleton()->process(0);322323CHECK_MESSAGE(324child_control_1->get_size().is_equal_approx(Size2(25, 100)),325"Child control with lower stretch ratio takes less space.");326327CHECK_MESSAGE(328child_control_2->get_size().is_equal_approx(Size2(75, 100)),329"Child control with higher stretch ratio takes more space.");330331CHECK_MESSAGE(332child_control_1->get_position().is_equal_approx(Point2(0, 0)),333"First expanding child control is aligned to the left.");334335CHECK_MESSAGE(336child_control_2->get_position().is_equal_approx(Point2(25, 0)),337"Second expanding child control is positioned after the first expanding child control.");338339memdelete(child_control_1);340memdelete(child_control_2);341}342343memdelete(hbox_container);344}345346TEST_CASE("[SceneTree][BoxContainer] VBoxContainer") {347VBoxContainer *vbox_container = memnew(VBoxContainer);348Window *root = SceneTree::get_singleton()->get_root();349root->add_child(vbox_container);350351vbox_container->set_size(Size2(100, 100));352SceneTree::get_singleton()->process(0);353354SUBCASE("Default behavior") {355Control *child_control = memnew(Control);356vbox_container->add_child(child_control);357SceneTree::get_singleton()->process(0);358359CHECK_MESSAGE(360vbox_container->get_alignment() == BoxContainer::ALIGNMENT_BEGIN,361"HBoxContainer alignment is set to ALIGNMENT_BEGIN by default.");362363CHECK_MESSAGE(364vbox_container->is_vertical(),365"VBoxContainer orientation is vertical.");366367CHECK_MESSAGE(368child_control->get_position().is_equal_approx(Point2(0, 0)),369"Child control is aligned to the left in ALIGNMENT_BEGIN mode.");370371CHECK_MESSAGE(372child_control->get_h_size_flags() == Control::SIZE_FILL,373"Child control horizontal size flags are set to SIZE_FILL by default.");374375CHECK_MESSAGE(376child_control->get_v_size_flags() == Control::SIZE_FILL,377"Child control vertical size flags are set to SIZE_FILL by default.");378379CHECK_MESSAGE(380child_control->get_size().is_equal_approx(Size2(100, 0)),381"Child control takes up minimum vertical space and matches container width by default.");382383memdelete(child_control);384}385386SUBCASE("Child Size Flags") {387Control *child_control = memnew(Control);388vbox_container->add_child(child_control);389child_control->set_custom_minimum_size(Size2(20, 20));390SceneTree::get_singleton()->process(0);391392CHECK_MESSAGE(393child_control->get_position().is_equal_approx(Point2(0, 0)),394"Child control is aligned to the top by default with SIZE_FILL.");395396child_control->set_v_size_flags(Control::SIZE_SHRINK_BEGIN);397SceneTree::get_singleton()->process(0);398399CHECK_MESSAGE(400child_control->get_position().is_equal_approx(Point2(0, 0)),401"Child control is aligned to the top of in SIZE_SHRINK_BEGIN vertical size flag mode.");402403child_control->set_v_size_flags(Control::SIZE_SHRINK_CENTER);404SceneTree::get_singleton()->process(0);405406CHECK_MESSAGE(407child_control->get_position().is_equal_approx(Point2(0, 0)),408"Child control is aligned to the top of in SIZE_SHRINK_CENTER vertical size flag mode.");409410child_control->set_v_size_flags(Control::SIZE_SHRINK_END);411SceneTree::get_singleton()->process(0);412413CHECK_MESSAGE(414child_control->get_position().is_equal_approx(Point2(0, 0)),415"Child control is aligned to the top of in SIZE_SHRINK_END vertical size flag mode.");416417child_control->set_v_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_BEGIN);418SceneTree::get_singleton()->process(0);419420CHECK_MESSAGE(421child_control->get_position().is_equal_approx(Point2(0, 0)),422"Child control is aligned to the top in SIZE_EXPAND | SIZE_SHRINK_BEGIN vertical size flag mode.");423424child_control->set_v_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_CENTER);425SceneTree::get_singleton()->process(0);426427CHECK_MESSAGE(428child_control->get_position().is_equal_approx(Point2(0, 40)),429"Child control is aligned to the center in SIZE_EXPAND | SIZE_SHRINK_CENTER vertical size flag mode.");430431child_control->set_v_size_flags(Control::SIZE_EXPAND | Control::SIZE_SHRINK_END);432SceneTree::get_singleton()->process(0);433434CHECK_MESSAGE(435child_control->get_position().is_equal_approx(Point2(0, 80)),436"Child control is aligned to the bottom in SIZE_EXPAND | SIZE_SHRINK_END vertical size flag mode.");437438memdelete(child_control);439}440441SUBCASE("Child Horizontal Size Flags") {442Control *child_control = memnew(Control);443vbox_container->add_child(child_control);444SceneTree::get_singleton()->process(0);445446CHECK_MESSAGE(447child_control->get_position().is_equal_approx(Point2(0, 0)),448"Child control is aligned to the left by default with SIZE_FILL.");449450child_control->set_h_size_flags(Control::SIZE_SHRINK_BEGIN);451SceneTree::get_singleton()->process(0);452453CHECK_MESSAGE(454child_control->get_position().is_equal_approx(Point2(0, 0)),455"Child control is aligned to the left of in SIZE_SHRINK_BEGIN horizontal size flag mode.");456457child_control->set_h_size_flags(Control::SIZE_SHRINK_CENTER);458SceneTree::get_singleton()->process(0);459460CHECK_MESSAGE(461child_control->get_position().is_equal_approx(Point2(50, 0)),462"Child control is aligned to the center of in SIZE_SHRINK_CENTER horizontal size flag mode.");463464child_control->set_h_size_flags(Control::SIZE_SHRINK_END);465SceneTree::get_singleton()->process(0);466467CHECK_MESSAGE(468child_control->get_position().is_equal_approx(Point2(100, 0)),469"Child control is aligned to the right of in SIZE_SHRINK_END horizontal size flag mode.");470471memdelete(child_control);472}473474SUBCASE("Child Alignment") {475Control *child_control = memnew(Control);476vbox_container->add_child(child_control);477SceneTree::get_singleton()->process(0);478479CHECK_MESSAGE(480child_control->get_position().is_equal_approx(Point2(0, 0)),481"Child control is aligned to the top in ALIGNMENT_BEGIN mode by default.");482483vbox_container->set_alignment(BoxContainer::ALIGNMENT_CENTER);484SceneTree::get_singleton()->process(0);485486CHECK_MESSAGE(487child_control->get_position().is_equal_approx(Point2(0, 50)),488"Child control is aligned to the center in ALIGNMENT_CENTER mode.");489490vbox_container->set_alignment(BoxContainer::ALIGNMENT_END);491SceneTree::get_singleton()->process(0);492493CHECK_MESSAGE(494child_control->get_position().is_equal_approx(Point2(0, 100)),495"Child control is aligned to the bottom in ALIGNMENT_END mode.");496497memdelete(child_control);498}499500SUBCASE("Child Separation") {501Control *child_control_1 = memnew(Control);502Control *child_control_2 = memnew(Control);503vbox_container->add_child(child_control_1);504vbox_container->add_child(child_control_2);505506vbox_container->add_theme_constant_override("separation", 10);507SceneTree::get_singleton()->process(0);508509CHECK_MESSAGE(510child_control_2->get_position().is_equal_approx(Point2(0, 10)),511"Child controls are separated by the specified separation value.");512513memdelete(child_control_1);514memdelete(child_control_2);515}516517SUBCASE("Spacers") {518Control *child_control_1 = memnew(Control);519Control *child_control_2 = memnew(Control);520vbox_container->add_child(child_control_1);521vbox_container->add_spacer();522vbox_container->add_child(child_control_2);523vbox_container->add_theme_constant_override("separation", 0);524SceneTree::get_singleton()->process(0);525526CHECK_MESSAGE(527child_control_2->get_position().is_equal_approx(Point2(0, 100)),528"Spacer pushes child controls apart.");529530memdelete(child_control_1);531memdelete(child_control_2);532}533534SUBCASE("Expanding children") {535Control *child_control_1 = memnew(Control);536Control *child_control_2 = memnew(Control);537vbox_container->add_child(child_control_1);538vbox_container->add_child(child_control_2);539vbox_container->add_theme_constant_override("separation", 0);540541child_control_1->set_v_size_flags(Control::SIZE_EXPAND_FILL);542SceneTree::get_singleton()->process(0);543544CHECK_MESSAGE(545child_control_1->get_size().is_equal_approx(Size2(100, 100)),546"One child control expands to fill available space.");547548CHECK_MESSAGE(549child_control_2->get_size().is_equal_approx(Size2(100, 0)),550"The non-expanding child control remains at minimum size.");551552CHECK_MESSAGE(553child_control_1->get_position().is_equal_approx(Point2(0, 0)),554"Expanding child control is aligned to the left.");555556CHECK_MESSAGE(557child_control_2->get_position().is_equal_approx(Point2(0, 100)),558"Non-expanding child control is positioned after the expanding child control.");559560child_control_2->set_custom_minimum_size(Size2(0, 20));561SceneTree::get_singleton()->process(0);562563CHECK_MESSAGE(564child_control_1->get_size().is_equal_approx(Size2(100, 80)),565"Expanding child control shrinks to accommodate the custom minimum size of the other child.");566567CHECK_MESSAGE(568child_control_2->get_size().is_equal_approx(Size2(100, 20)),569"The non-expanding child control respects its custom minimum size.");570571CHECK_MESSAGE(572child_control_1->get_position().is_equal_approx(Point2(0, 0)),573"Expanding child control is aligned to the left.");574575CHECK_MESSAGE(576child_control_2->get_position().is_equal_approx(Point2(0, 80)),577"Non-expanding child control is positioned after the expanding child control.");578579child_control_2->set_v_size_flags(Control::SIZE_EXPAND_FILL);580SceneTree::get_singleton()->process(0);581582CHECK_MESSAGE(583child_control_1->get_size().is_equal_approx(Size2(100, 50)),584"Both child controls expand equally to fill available space.");585586CHECK_MESSAGE(587child_control_2->get_size().is_equal_approx(Size2(100, 50)),588"Both child controls expand equally to fill available space.");589590CHECK_MESSAGE(591child_control_1->get_position().is_equal_approx(Point2(0, 0)),592"First expanding child control is aligned to the left.");593594CHECK_MESSAGE(595child_control_2->get_position().is_equal_approx(Point2(0, 50)),596"Second expanding child control is positioned after the first expanding child control.");597598child_control_2->set_stretch_ratio(3);599SceneTree::get_singleton()->process(0);600601CHECK_MESSAGE(602child_control_1->get_size().is_equal_approx(Size2(100, 25)),603"Child control with lower stretch ratio takes less space.");604605CHECK_MESSAGE(606child_control_2->get_size().is_equal_approx(Size2(100, 75)),607"Child control with higher stretch ratio takes more space.");608609CHECK_MESSAGE(610child_control_1->get_position().is_equal_approx(Point2(0, 0)),611"First expanding child control is aligned to the left.");612613CHECK_MESSAGE(614child_control_2->get_position().is_equal_approx(Point2(0, 25)),615"Second expanding child control is positioned after the first expanding child control.");616617memdelete(child_control_1);618memdelete(child_control_2);619}620621memdelete(vbox_container);622}623624} // namespace TestBoxContainer625626627