Path: blob/master/tests/scene/test_split_container.h
20920 views
/**************************************************************************/1/* test_split_container.h */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#pragma once3132#include "scene/gui/split_container.h"33#include "scene/main/window.h"3435#include "tests/test_macros.h"3637namespace TestSplitContainer {3839#define CHECK_RECTS(m_rects, m_child_rects) \40CHECK(m_rects.size() == m_child_rects.size()); \41for (int i = 0; i < (int)m_child_rects.size(); i++) { \42CHECK_MESSAGE(m_child_rects[i] == m_rects[i], vformat("Child %s is the wrong size. Child rect: %s, expected: %s.", i, m_child_rects[i], m_rects[i])); \43}4445static inline Vector<Rect2> get_rects_multi(SplitContainer *p_sc, const Vector<int> &p_positions, int p_sep, bool p_horizontal = true) {46// p_positions is the top/left side of the dragger.47Vector<Rect2> rects;48int last_pos = 0;49for (int i = 0; i < (int)p_positions.size() + 1; i++) {50const int pos = i >= (int)p_positions.size() ? p_sc->get_size()[p_horizontal ? 0 : 1] : p_positions[i];51Rect2 rect;52if (p_horizontal) {53rect.size.y = p_sc->get_size().y;54rect.position.x = last_pos;55rect.size.x = pos - last_pos;56} else {57rect.size.x = p_sc->get_size().x;58rect.position.y = last_pos;59rect.size.y = pos - last_pos;60}61rects.push_back(rect);62last_pos = pos + p_sep;63}64return rects;65}6667static inline Vector<Rect2> get_rects(SplitContainer *p_sc, int p_position, int p_sep, bool p_horizontal = true) {68return get_rects_multi(p_sc, Vector<int>({ p_position }), p_sep, p_horizontal);69}7071static inline Vector<Rect2> get_rects_multi_rtl(SplitContainer *p_sc, const Vector<int> &p_positions, int p_sep) {72Vector<Rect2> rects;73int last_pos = p_sc->get_size().x;74for (int i = 0; i < (int)p_positions.size() + 1; i++) {75const int pos = i >= (int)p_positions.size() ? 0 : p_sc->get_size().x - p_positions[i];76Rect2 rect;77rect.size.y = p_sc->get_size().y;78rect.position.x = pos;79rect.size.x = last_pos - pos;80rects.push_back(rect);81last_pos = pos - p_sep;82}83return rects;84}8586static inline Vector<Rect2> get_rects_rtl(SplitContainer *p_sc, int p_position, int p_sep) {87return get_rects_multi_rtl(p_sc, Vector<int>({ p_position }), p_sep);88}8990static inline Vector<Rect2> get_child_rects(SplitContainer *p_sc) {91Vector<Rect2> rects;92for (int i = 0; i < p_sc->get_child_count(false); i++) {93Control *c = Object::cast_to<Control>(p_sc->get_child(i, false));94if (!c || !c->is_visible()) {95continue;96}97rects.push_back(c->get_rect());98}99return rects;100}101102static inline void set_size_flags(SplitContainer *p_sc, Vector<float> p_expand_ratios, bool p_horizontal = true) {103for (int i = 0; i < p_sc->get_child_count(false); i++) {104Control *c = Object::cast_to<Control>(p_sc->get_child(i, false));105if (!c || !c->is_visible()) {106continue;107}108float ratio = p_expand_ratios[i];109if (p_horizontal) {110c->set_h_size_flags(ratio > 0 ? Control::SIZE_EXPAND_FILL : Control::SIZE_FILL);111} else {112c->set_v_size_flags(ratio > 0 ? Control::SIZE_EXPAND_FILL : Control::SIZE_FILL);113}114if (ratio > 0) {115c->set_stretch_ratio(ratio);116}117}118MessageQueue::get_singleton()->flush();119}120121TEST_CASE("[SceneTree][SplitContainer] Add and remove children") {122SplitContainer *split_container = memnew(SplitContainer);123split_container->set_size(Size2(500, 500));124SceneTree::get_singleton()->get_root()->add_child(split_container);125126SUBCASE("[SplitContainer] One child") {127Control *child_a = memnew(Control);128split_container->add_child(child_a);129MessageQueue::get_singleton()->flush();130131// One child will fill the entire area.132CHECK(child_a->get_rect() == split_container->get_rect());133134split_container->set_vertical(true);135CHECK(child_a->get_rect() == split_container->get_rect());136137memdelete(child_a);138}139140SUBCASE("[SplitContainer] Preserve split offset") {141// The split offset is preserved through adding, removing, and changing visibility of children.142split_container->set_split_offset(100);143CHECK(split_container->get_split_offset() == 100);144145Control *child_a = memnew(Control);146split_container->add_child(child_a);147MessageQueue::get_singleton()->flush();148CHECK(split_container->get_split_offset() == 100);149150Control *child_b = memnew(Control);151split_container->add_child(child_b);152MessageQueue::get_singleton()->flush();153CHECK(split_container->get_split_offset() == 100);154155child_a->hide();156MessageQueue::get_singleton()->flush();157CHECK(split_container->get_split_offset() == 100);158159child_b->hide();160MessageQueue::get_singleton()->flush();161CHECK(split_container->get_split_offset() == 100);162163child_b->show();164MessageQueue::get_singleton()->flush();165CHECK(split_container->get_split_offset() == 100);166167child_a->show();168MessageQueue::get_singleton()->flush();169CHECK(split_container->get_split_offset() == 100);170171split_container->remove_child(child_a);172MessageQueue::get_singleton()->flush();173CHECK(split_container->get_split_offset() == 100);174175split_container->add_child(child_a);176MessageQueue::get_singleton()->flush();177CHECK(split_container->get_split_offset() == 100);178179memdelete(child_a);180memdelete(child_b);181}182183memdelete(split_container);184}185186TEST_CASE("[SceneTree][SplitContainer] Dragger visibility") {187SplitContainer *split_container = memnew(SplitContainer);188split_container->set_size(Size2(500, 500));189SceneTree::get_singleton()->get_root()->add_child(split_container);190Control *child_a = memnew(Control);191Control *child_b = memnew(Control);192split_container->add_child(child_a);193split_container->add_child(child_b);194SplitContainerDragger *dragger = Object::cast_to<SplitContainerDragger>(split_container->get_child(2, true));195196split_container->add_theme_constant_override("autohide", 0);197MessageQueue::get_singleton()->flush();198199const int sep_constant = split_container->get_theme_constant("separation");200const Size2i sep = Size2i(MAX(sep_constant, split_container->get_theme_icon("h_grabber")->get_width()), MAX(sep_constant, split_container->get_theme_icon("v_grabber")->get_height()));201202SUBCASE("[SplitContainer] Visibility based on child count") {203split_container->remove_child(child_a);204split_container->remove_child(child_b);205MessageQueue::get_singleton()->flush();206207// No children, not visible.208CHECK_FALSE(dragger->is_visible());209210// Add one child, not visible.211split_container->add_child(child_a);212MessageQueue::get_singleton()->flush();213CHECK_FALSE(dragger->is_visible());214215// Two children, visible.216split_container->add_child(child_b);217MessageQueue::get_singleton()->flush();218CHECK(dragger->is_visible());219220// Remove a child, not visible.221split_container->remove_child(child_b);222MessageQueue::get_singleton()->flush();223CHECK_FALSE(dragger->is_visible());224}225226SUBCASE("[SplitContainer] Set dragger visibility") {227split_container->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);228MessageQueue::get_singleton()->flush();229CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));230// Can't check the visibility since it happens in draw.231232split_container->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED);233MessageQueue::get_singleton()->flush();234CHECK_RECTS(get_rects(split_container, 0, 0), get_child_rects(split_container));235236split_container->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE);237MessageQueue::get_singleton()->flush();238CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));239}240241SUBCASE("[SplitContainer] Not visible when collapsed") {242split_container->set_collapsed(true);243MessageQueue::get_singleton()->flush();244CHECK_FALSE(dragger->is_visible());245246split_container->set_collapsed(false);247MessageQueue::get_singleton()->flush();248CHECK(dragger->is_visible());249}250251memdelete(child_a);252memdelete(child_b);253memdelete(split_container);254}255256TEST_CASE("[SceneTree][SplitContainer] Collapsed") {257DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());258259SplitContainer *split_container = memnew(SplitContainer);260split_container->set_size(Size2(500, 500));261SceneTree::get_singleton()->get_root()->add_child(split_container);262Control *child_a = memnew(Control);263split_container->add_child(child_a);264Control *child_b = memnew(Control);265split_container->add_child(child_b);266MessageQueue::get_singleton()->flush();267268const int sep_constant = split_container->get_theme_constant("separation");269const Size2i sep = Size2i(MAX(sep_constant, split_container->get_theme_icon("h_grabber")->get_width()), MAX(sep_constant, split_container->get_theme_icon("v_grabber")->get_height()));270271SUBCASE("[SplitContainer] Dragging and cursor") {272split_container->set_collapsed(true);273274// Cursor is default.275SEND_GUI_MOUSE_MOTION_EVENT(Point2(1, 1), MouseButtonMask::NONE, Key::NONE);276CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_ARROW);277278// Dragger is disabled, cannot drag.279SEND_GUI_MOUSE_BUTTON_EVENT(Point2(1, 1), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);280MessageQueue::get_singleton()->flush();281CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));282CHECK(split_container->get_split_offset() == 0);283SEND_GUI_MOUSE_MOTION_EVENT(Point2(10, 1), MouseButtonMask::LEFT, Key::NONE);284MessageQueue::get_singleton()->flush();285CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));286CHECK(split_container->get_split_offset() == 0);287}288289SUBCASE("[SplitContainer] No expand flags") {290int def_pos = 0;291292split_container->set_split_offset(10);293MessageQueue::get_singleton()->flush();294CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));295296split_container->set_collapsed(true);297MessageQueue::get_singleton()->flush();298299// The split offset is treated as 0 when collapsed.300CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));301CHECK(split_container->get_split_offset() == 10);302}303304SUBCASE("[SplitContainer] First child expanded") {305int def_pos = split_container->get_size().x - sep.x;306child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);307split_container->set_split_offset(-10);308MessageQueue::get_singleton()->flush();309310CHECK_RECTS(get_rects(split_container, def_pos - 10, sep.x), get_child_rects(split_container));311312split_container->set_collapsed(true);313MessageQueue::get_singleton()->flush();314315// The split offset is treated as 0 when collapsed.316CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));317CHECK(split_container->get_split_offset() == -10);318}319320SUBCASE("[SplitContainer] Second child expanded") {321int def_pos = 0;322child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);323split_container->set_split_offset(10);324MessageQueue::get_singleton()->flush();325326CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));327328split_container->set_collapsed(true);329MessageQueue::get_singleton()->flush();330331// The split offset is treated as 0 when collapsed.332CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));333CHECK(split_container->get_split_offset() == 10);334}335336SUBCASE("[SplitContainer] Both children expanded") {337int def_pos = (split_container->get_size().y - sep.y) / 2;338child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);339child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);340split_container->set_split_offset(10);341MessageQueue::get_singleton()->flush();342343CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));344345split_container->set_collapsed(true);346MessageQueue::get_singleton()->flush();347348// The split offset is treated as 0 when collapsed.349CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));350CHECK(split_container->get_split_offset() == 10);351}352353memdelete(child_a);354memdelete(child_b);355memdelete(split_container);356}357358TEST_CASE("[SceneTree][SplitContainer] Cursor shape") {359DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());360361SplitContainer *split_container = memnew(SplitContainer);362split_container->set_size(Size2(500, 500));363SceneTree::get_singleton()->get_root()->add_child(split_container);364Control *child_a = memnew(Control);365split_container->add_child(child_a);366Control *child_b = memnew(Control);367split_container->add_child(child_b);368MessageQueue::get_singleton()->flush();369370Point2 on_dragger = Point2(1, 1);371Point2 not_on_dragger = Point2(50, 50);372373// Default cursor shape.374SEND_GUI_MOUSE_MOTION_EVENT(not_on_dragger, MouseButtonMask::NONE, Key::NONE);375CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_ARROW);376377// Horizontal cursor shape.378SEND_GUI_MOUSE_MOTION_EVENT(on_dragger, MouseButtonMask::NONE, Key::NONE);379CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_HSPLIT);380381// Vertical cursor shape.382split_container->set_vertical(true);383SEND_GUI_MOUSE_MOTION_EVENT(on_dragger, MouseButtonMask::NONE, Key::NONE);384CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_VSPLIT);385386// Move off, default cursor shape.387SEND_GUI_MOUSE_MOTION_EVENT(not_on_dragger, MouseButtonMask::NONE, Key::NONE);388CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_ARROW);389390memdelete(child_a);391memdelete(child_b);392memdelete(split_container);393}394395TEST_CASE("[SceneTree][SplitContainer] Two children") {396SplitContainer *split_container = memnew(SplitContainer);397split_container->set_size(Size2(500, 500));398SceneTree::get_singleton()->get_root()->add_child(split_container);399Control *child_a = memnew(Control);400Control *child_b = memnew(Control);401split_container->add_child(child_a);402split_container->add_child(child_b);403MessageQueue::get_singleton()->flush();404405const int sep_constant = split_container->get_theme_constant("separation");406const Size2i sep = Size2i(MAX(sep_constant, split_container->get_theme_icon("h_grabber")->get_width()), MAX(sep_constant, split_container->get_theme_icon("v_grabber")->get_height()));407408SUBCASE("[SplitContainer] Minimum size") {409// Minimum size is the sum of both children's minimum sizes and the separator depending on the vertical axis.410child_a->set_custom_minimum_size(Size2(100, 200));411child_b->set_custom_minimum_size(Size2(100, 200));412MessageQueue::get_singleton()->flush();413414Size2 min_size = split_container->get_minimum_size();415CHECK(min_size.x == 200 + sep.x);416CHECK(min_size.y == 200);417418split_container->set_vertical(true);419MessageQueue::get_singleton()->flush();420min_size = split_container->get_minimum_size();421CHECK(min_size.x == 100);422CHECK(min_size.y == 400 + sep.y);423}424425SUBCASE("[SplitContainer] Default position") {426SUBCASE("[SplitContainer] Vertical") {427// Make sure clamping the split offset doesn't change it or the position.428split_container->set_vertical(true);429430// No expand flags set.431MessageQueue::get_singleton()->flush();432int def_pos = 0;433CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));434split_container->clamp_split_offset();435MessageQueue::get_singleton()->flush();436CHECK(split_container->get_split_offset() == 0);437CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));438439// First expand flags set.440child_a->set_v_size_flags(Control::SIZE_EXPAND_FILL);441child_b->set_v_size_flags(Control::SIZE_FILL);442MessageQueue::get_singleton()->flush();443def_pos = split_container->get_size().y - sep.y;444CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));445split_container->clamp_split_offset();446MessageQueue::get_singleton()->flush();447CHECK(split_container->get_split_offset() == 0);448CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));449450// Second expand flags set.451child_a->set_v_size_flags(Control::SIZE_FILL);452child_b->set_v_size_flags(Control::SIZE_EXPAND_FILL);453MessageQueue::get_singleton()->flush();454def_pos = 0;455CHECK_RECTS(get_rects(split_container, 0, sep.y, false), get_child_rects(split_container));456split_container->clamp_split_offset();457MessageQueue::get_singleton()->flush();458CHECK(split_container->get_split_offset() == 0);459CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));460461// Both expand flags set.462child_a->set_v_size_flags(Control::SIZE_EXPAND_FILL);463child_b->set_v_size_flags(Control::SIZE_EXPAND_FILL);464MessageQueue::get_singleton()->flush();465def_pos = (split_container->get_size().y - sep.y) / 2;466CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));467split_container->clamp_split_offset();468MessageQueue::get_singleton()->flush();469CHECK(split_container->get_split_offset() == 0);470CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));471472// Unequal stretch ratios.473child_a->set_stretch_ratio(2.0);474MessageQueue::get_singleton()->flush();475def_pos = (split_container->get_size().y * 2 / 3) - sep.y / 2;476CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));477split_container->clamp_split_offset();478MessageQueue::get_singleton()->flush();479CHECK(split_container->get_split_offset() == 0);480CHECK_RECTS(get_rects(split_container, def_pos, sep.y, false), get_child_rects(split_container));481}482483SUBCASE("[SplitContainer] Right to left") {484split_container->set_layout_direction(Control::LAYOUT_DIRECTION_RTL);485split_container->set_position(Point2(0, 0));486487// No expand flags set.488MessageQueue::get_singleton()->flush();489int def_pos = 0;490CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));491split_container->clamp_split_offset();492MessageQueue::get_singleton()->flush();493CHECK(split_container->get_split_offset() == 0);494CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));495496// First expand flags set.497child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);498child_b->set_h_size_flags(Control::SIZE_FILL);499MessageQueue::get_singleton()->flush();500def_pos = split_container->get_size().y - sep.y;501CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));502split_container->clamp_split_offset();503MessageQueue::get_singleton()->flush();504CHECK(split_container->get_split_offset() == 0);505CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));506507// Second expand flags set.508child_a->set_h_size_flags(Control::SIZE_FILL);509child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);510MessageQueue::get_singleton()->flush();511def_pos = 0;512CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));513split_container->clamp_split_offset();514MessageQueue::get_singleton()->flush();515CHECK(split_container->get_split_offset() == 0);516CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));517518// Both expand flags set.519child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);520child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);521MessageQueue::get_singleton()->flush();522def_pos = (split_container->get_size().y - sep.y) / 2;523CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));524split_container->clamp_split_offset();525MessageQueue::get_singleton()->flush();526CHECK(split_container->get_split_offset() == 0);527CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));528529// Unequal stretch ratios.530child_a->set_stretch_ratio(2.0);531MessageQueue::get_singleton()->flush();532def_pos = (split_container->get_size().y * 2 / 3) - sep.y / 2;533CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));534split_container->clamp_split_offset();535MessageQueue::get_singleton()->flush();536CHECK(split_container->get_split_offset() == 0);537CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));538}539540SUBCASE("[SplitContainer] No expand flags") {541int def_pos = 0;542543CHECK(split_container->get_split_offset() == 0);544CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));545546split_container->clamp_split_offset();547MessageQueue::get_singleton()->flush();548CHECK(split_container->get_split_offset() == 0);549CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));550551// Minimum sizes affect default position.552553// First child with minimum size.554child_a->set_custom_minimum_size(Size2(400, 0));555MessageQueue::get_singleton()->flush();556def_pos = 400;557CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));558split_container->clamp_split_offset();559MessageQueue::get_singleton()->flush();560CHECK(split_container->get_split_offset() == def_pos);561CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));562563// Second child with minimum size.564child_a->set_custom_minimum_size(Size2(0, 0));565child_b->set_custom_minimum_size(Size2(400, 0));566MessageQueue::get_singleton()->flush();567def_pos = split_container->get_size().x - 400 - sep.x;568CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));569split_container->clamp_split_offset();570MessageQueue::get_singleton()->flush();571CHECK(split_container->get_split_offset() == def_pos);572CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));573574// Both children with minimum size.575child_a->set_custom_minimum_size(Size2(200, 0));576child_b->set_custom_minimum_size(Size2(288, 0));577MessageQueue::get_singleton()->flush();578def_pos = 200;579CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));580split_container->clamp_split_offset();581MessageQueue::get_singleton()->flush();582CHECK(split_container->get_split_offset() == def_pos);583CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));584}585586SUBCASE("[SplitContainer] First child expanded") {587const int def_pos = split_container->get_size().x - sep.x;588child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);589MessageQueue::get_singleton()->flush();590591CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));592593split_container->clamp_split_offset();594MessageQueue::get_singleton()->flush();595CHECK(split_container->get_split_offset() == 0);596CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));597598// Minimum sizes affect default position.599600// First child with minimum size.601child_a->set_custom_minimum_size(Size2(400, 0));602MessageQueue::get_singleton()->flush();603CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));604split_container->clamp_split_offset();605MessageQueue::get_singleton()->flush();606CHECK(split_container->get_split_offset() == 0);607CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));608609// Second child with minimum size.610child_a->set_custom_minimum_size(Size2(0, 0));611child_b->set_custom_minimum_size(Size2(400, 0));612MessageQueue::get_singleton()->flush();613int pos = split_container->get_size().x - 400 - sep.x;614CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));615split_container->clamp_split_offset();616MessageQueue::get_singleton()->flush();617CHECK(split_container->get_split_offset() == pos - def_pos);618CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));619620// Both children with minimum size.621child_a->set_custom_minimum_size(Size2(200, 0));622child_b->set_custom_minimum_size(Size2(288, 0));623MessageQueue::get_singleton()->flush();624pos = 200;625CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));626split_container->clamp_split_offset();627MessageQueue::get_singleton()->flush();628CHECK(split_container->get_split_offset() == pos - def_pos);629CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));630}631632SUBCASE("[SplitContainer] Second child expanded") {633int def_pos = 0;634child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);635MessageQueue::get_singleton()->flush();636637CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));638639split_container->clamp_split_offset();640MessageQueue::get_singleton()->flush();641CHECK(split_container->get_split_offset() == 0);642CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));643644// Minimum sizes affect default position.645646// First child with minimum size.647child_a->set_custom_minimum_size(Size2(400, 0));648MessageQueue::get_singleton()->flush();649def_pos = 400;650CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));651split_container->clamp_split_offset();652MessageQueue::get_singleton()->flush();653CHECK(split_container->get_split_offset() == def_pos);654CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));655656// Second child with minimum size.657child_a->set_custom_minimum_size(Size2(0, 0));658child_b->set_custom_minimum_size(Size2(400, 0));659MessageQueue::get_singleton()->flush();660def_pos = 500 - 400 - sep.x;661CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));662split_container->clamp_split_offset();663MessageQueue::get_singleton()->flush();664CHECK(split_container->get_split_offset() == def_pos);665CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));666667// Both children with minimum size.668child_a->set_custom_minimum_size(Size2(200, 0));669child_b->set_custom_minimum_size(Size2(288, 0));670MessageQueue::get_singleton()->flush();671def_pos = 200;672CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));673split_container->clamp_split_offset();674MessageQueue::get_singleton()->flush();675CHECK(split_container->get_split_offset() == def_pos);676CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));677}678679SUBCASE("[SplitContainer] Both children expanded") {680const int def_pos = (split_container->get_size().x - sep.x) / 2;681child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);682child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);683MessageQueue::get_singleton()->flush();684685CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));686687split_container->clamp_split_offset();688MessageQueue::get_singleton()->flush();689CHECK(split_container->get_split_offset() == 0);690CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));691692// Minimum sizes affect default position.693694// First child with minimum size.695child_a->set_custom_minimum_size(Size2(400, 0));696MessageQueue::get_singleton()->flush();697int pos = 400;698CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));699split_container->clamp_split_offset();700MessageQueue::get_singleton()->flush();701CHECK(split_container->get_split_offset() == pos - def_pos);702CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));703704// Second child with minimum size.705child_a->set_custom_minimum_size(Size2(0, 0));706child_b->set_custom_minimum_size(Size2(400, 0));707MessageQueue::get_singleton()->flush();708pos = split_container->get_size().x - 400 - sep.x;709CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));710split_container->clamp_split_offset();711MessageQueue::get_singleton()->flush();712CHECK(split_container->get_split_offset() == pos - def_pos);713CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));714715// Both children with minimum size.716child_a->set_custom_minimum_size(Size2(200, 0));717child_b->set_custom_minimum_size(Size2(288, 0));718MessageQueue::get_singleton()->flush();719pos = 200;720CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));721split_container->clamp_split_offset();722MessageQueue::get_singleton()->flush();723CHECK(split_container->get_split_offset() == pos - def_pos);724CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));725}726727SUBCASE("[SplitContainer] Unequal stretch ratios") {728const int def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;729child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);730child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);731child_a->set_stretch_ratio(2.0);732MessageQueue::get_singleton()->flush();733734CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));735736split_container->clamp_split_offset();737MessageQueue::get_singleton()->flush();738CHECK(split_container->get_split_offset() == 0);739CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));740741// Minimum sizes affect default position.742743// First child with minimum size.744child_a->set_custom_minimum_size(Size2(400, 0));745MessageQueue::get_singleton()->flush();746int pos = 400;747CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));748split_container->clamp_split_offset();749MessageQueue::get_singleton()->flush();750CHECK(split_container->get_split_offset() == pos - def_pos);751CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));752753// Second child with minimum size.754child_a->set_custom_minimum_size(Size2(0, 0));755child_b->set_custom_minimum_size(Size2(400, 0));756MessageQueue::get_singleton()->flush();757pos = split_container->get_size().x - 400 - sep.x;758CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));759split_container->clamp_split_offset();760MessageQueue::get_singleton()->flush();761CHECK(split_container->get_split_offset() == pos - def_pos);762CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));763764// Both children with minimum size.765child_a->set_custom_minimum_size(Size2(200, 0));766child_b->set_custom_minimum_size(Size2(288, 0));767MessageQueue::get_singleton()->flush();768pos = 200;769CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));770split_container->clamp_split_offset();771MessageQueue::get_singleton()->flush();772CHECK(split_container->get_split_offset() == pos - def_pos);773CHECK_RECTS(get_rects(split_container, pos, sep.x), get_child_rects(split_container));774}775}776777SUBCASE("[SplitContainer] Set split offset") {778SUBCASE("[SplitContainer] Right to left") {779split_container->set_layout_direction(Control::LAYOUT_DIRECTION_RTL);780split_container->set_position(Point2(0, 0));781int def_pos = 0;782// Positive.783split_container->set_split_offset(10);784MessageQueue::get_singleton()->flush();785CHECK(split_container->get_split_offset() == 10);786CHECK_RECTS(get_rects_rtl(split_container, def_pos + 10, sep.y), get_child_rects(split_container));787788// Negative.789split_container->set_split_offset(-10);790MessageQueue::get_singleton()->flush();791CHECK(split_container->get_split_offset() == -10);792CHECK_RECTS(get_rects_rtl(split_container, def_pos, sep.y), get_child_rects(split_container));793}794795SUBCASE("[SplitContainer] No expand flags") {796int def_pos = 0;797798// Positive.799split_container->set_split_offset(10);800MessageQueue::get_singleton()->flush();801CHECK(split_container->get_split_offset() == 10);802CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));803804// Negative.805split_container->set_split_offset(-10);806MessageQueue::get_singleton()->flush();807CHECK(split_container->get_split_offset() == -10);808CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));809810// Clamped.811split_container->set_split_offset(1000);812MessageQueue::get_singleton()->flush();813CHECK(split_container->get_split_offset() == 1000);814CHECK_RECTS(get_rects(split_container, split_container->get_size().x - sep.x, sep.x), get_child_rects(split_container));815}816817SUBCASE("[SplitContainer] First child expanded") {818int def_pos = split_container->get_size().x - sep.x;819child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);820MessageQueue::get_singleton()->flush();821822// Positive.823split_container->set_split_offset(10);824MessageQueue::get_singleton()->flush();825CHECK(split_container->get_split_offset() == 10);826CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));827828// Negative.829split_container->set_split_offset(-10);830MessageQueue::get_singleton()->flush();831CHECK(split_container->get_split_offset() == -10);832CHECK_RECTS(get_rects(split_container, def_pos - 10, sep.x), get_child_rects(split_container));833834// Clamped.835split_container->set_split_offset(-1000);836MessageQueue::get_singleton()->flush();837CHECK(split_container->get_split_offset() == -1000);838CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));839}840841SUBCASE("[SplitContainer] Second child expanded") {842int def_pos = 0;843child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);844MessageQueue::get_singleton()->flush();845846// Positive.847split_container->set_split_offset(10);848MessageQueue::get_singleton()->flush();849CHECK(split_container->get_split_offset() == 10);850CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));851852// Negative.853split_container->set_split_offset(-10);854MessageQueue::get_singleton()->flush();855CHECK(split_container->get_split_offset() == -10);856CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));857858// Clamped.859split_container->set_split_offset(1000);860MessageQueue::get_singleton()->flush();861CHECK(split_container->get_split_offset() == 1000);862CHECK_RECTS(get_rects(split_container, split_container->get_size().x - sep.x, sep.x), get_child_rects(split_container));863}864865SUBCASE("[SplitContainer] Both children expanded") {866int def_pos = (split_container->get_size().x - sep.x) / 2;867child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);868child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);869MessageQueue::get_singleton()->flush();870871// Positive.872split_container->set_split_offset(10);873MessageQueue::get_singleton()->flush();874CHECK(split_container->get_split_offset() == 10);875CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));876877// Negative.878split_container->set_split_offset(-10);879MessageQueue::get_singleton()->flush();880CHECK(split_container->get_split_offset() == -10);881CHECK_RECTS(get_rects(split_container, def_pos - 10, sep.x), get_child_rects(split_container));882883// Clamped positive.884split_container->set_split_offset(1000);885MessageQueue::get_singleton()->flush();886CHECK(split_container->get_split_offset() == 1000);887CHECK_RECTS(get_rects(split_container, split_container->get_size().x - sep.x, sep.x), get_child_rects(split_container));888889// Clamped negative.890split_container->set_split_offset(-1000);891MessageQueue::get_singleton()->flush();892CHECK(split_container->get_split_offset() == -1000);893CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));894}895896SUBCASE("[SplitContainer] Unequal stretch ratios") {897int def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;898child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);899child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);900child_a->set_stretch_ratio(2.0);901MessageQueue::get_singleton()->flush();902903// Positive.904split_container->set_split_offset(10);905MessageQueue::get_singleton()->flush();906CHECK(split_container->get_split_offset() == 10);907CHECK_RECTS(get_rects(split_container, def_pos + 10, sep.x), get_child_rects(split_container));908909// Negative.910split_container->set_split_offset(-10);911MessageQueue::get_singleton()->flush();912CHECK(split_container->get_split_offset() == -10);913CHECK_RECTS(get_rects(split_container, def_pos - 10, sep.x), get_child_rects(split_container));914915// Clamped positive.916split_container->set_split_offset(1000);917MessageQueue::get_singleton()->flush();918CHECK(split_container->get_split_offset() == 1000);919CHECK_RECTS(get_rects(split_container, split_container->get_size().x - sep.x, sep.x), get_child_rects(split_container));920921// Clamped negative.922split_container->set_split_offset(-1000);923MessageQueue::get_singleton()->flush();924CHECK(split_container->get_split_offset() == -1000);925CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));926}927}928929SUBCASE("[SplitContainer] Keep split offset when changing minimum size") {930SUBCASE("[SplitContainer] No expand flags") {931int def_pos = 0;932933split_container->set_split_offset(100);934child_a->set_custom_minimum_size(Size2(10, 0));935MessageQueue::get_singleton()->flush();936CHECK(split_container->get_split_offset() == 100);937CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));938939child_a->set_custom_minimum_size(Size2(50, 0));940MessageQueue::get_singleton()->flush();941CHECK(split_container->get_split_offset() == 100);942CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));943}944945SUBCASE("[SplitContainer] First child expanded") {946int def_pos = split_container->get_size().x - sep.x;947child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);948MessageQueue::get_singleton()->flush();949950split_container->set_split_offset(-100);951child_b->set_custom_minimum_size(Size2(10, 0));952MessageQueue::get_singleton()->flush();953CHECK(split_container->get_split_offset() == -100);954CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));955956child_b->set_custom_minimum_size(Size2(50, 0));957MessageQueue::get_singleton()->flush();958CHECK(split_container->get_split_offset() == -100);959CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));960}961962SUBCASE("[SplitContainer] Second child expanded") {963int def_pos = 0;964child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);965MessageQueue::get_singleton()->flush();966967split_container->set_split_offset(100);968child_a->set_custom_minimum_size(Size2(10, 0));969MessageQueue::get_singleton()->flush();970CHECK(split_container->get_split_offset() == 100);971CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));972973child_a->set_custom_minimum_size(Size2(50, 0));974MessageQueue::get_singleton()->flush();975CHECK(split_container->get_split_offset() == 100);976CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));977}978979SUBCASE("[SplitContainer] Both children expanded") {980int def_pos = (split_container->get_size().x - sep.x) / 2;981child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);982child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);983MessageQueue::get_singleton()->flush();984985split_container->set_split_offset(20);986child_a->set_custom_minimum_size(Size2(10, 0));987child_b->set_custom_minimum_size(Size2(10, 0));988MessageQueue::get_singleton()->flush();989CHECK(split_container->get_split_offset() == 20);990CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));991992child_a->set_custom_minimum_size(Size2(50, 0));993child_b->set_custom_minimum_size(Size2(50, 0));994MessageQueue::get_singleton()->flush();995CHECK(split_container->get_split_offset() == 20);996CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));997}998}9991000SUBCASE("[SplitContainer] Keep split offset when changing visibility") {1001SUBCASE("[SplitContainer] No expand flags") {1002int def_pos = 0;1003split_container->set_split_offset(100);10041005child_a->hide();1006MessageQueue::get_singleton()->flush();1007CHECK(split_container->get_split_offset() == 100);1008CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10091010child_b->hide();1011MessageQueue::get_singleton()->flush();1012CHECK(split_container->get_split_offset() == 100);10131014child_a->show();1015MessageQueue::get_singleton()->flush();1016CHECK(split_container->get_split_offset() == 100);1017CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10181019child_b->show();1020MessageQueue::get_singleton()->flush();1021CHECK(split_container->get_split_offset() == 100);1022CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1023}10241025SUBCASE("[SplitContainer] First child expanded") {1026int def_pos = split_container->get_size().x - sep.x;1027child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1028MessageQueue::get_singleton()->flush();1029split_container->set_split_offset(-100);10301031child_a->hide();1032MessageQueue::get_singleton()->flush();1033CHECK(split_container->get_split_offset() == -100);1034CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10351036child_b->hide();1037MessageQueue::get_singleton()->flush();1038CHECK(split_container->get_split_offset() == -100);10391040child_a->show();1041MessageQueue::get_singleton()->flush();1042CHECK(split_container->get_split_offset() == -100);1043CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10441045child_b->show();1046MessageQueue::get_singleton()->flush();1047CHECK(split_container->get_split_offset() == -100);1048CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));1049}10501051SUBCASE("[SplitContainer] Second child expanded") {1052int def_pos = 0;1053child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1054MessageQueue::get_singleton()->flush();1055split_container->set_split_offset(100);10561057child_a->hide();1058MessageQueue::get_singleton()->flush();1059CHECK(split_container->get_split_offset() == 100);1060CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10611062child_b->hide();1063MessageQueue::get_singleton()->flush();1064CHECK(split_container->get_split_offset() == 100);10651066child_a->show();1067MessageQueue::get_singleton()->flush();1068CHECK(split_container->get_split_offset() == 100);1069CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10701071child_b->show();1072MessageQueue::get_singleton()->flush();1073CHECK(split_container->get_split_offset() == 100);1074CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1075}10761077SUBCASE("[SplitContainer] Both children expanded") {1078int def_pos = (split_container->get_size().x - sep.x) / 2;1079child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1080child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1081MessageQueue::get_singleton()->flush();1082split_container->set_split_offset(20);10831084child_a->hide();1085MessageQueue::get_singleton()->flush();1086CHECK(split_container->get_split_offset() == 20);1087CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10881089child_b->hide();1090MessageQueue::get_singleton()->flush();1091CHECK(split_container->get_split_offset() == 20);10921093child_a->show();1094MessageQueue::get_singleton()->flush();1095CHECK(split_container->get_split_offset() == 20);1096CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));10971098child_b->show();1099MessageQueue::get_singleton()->flush();1100CHECK(split_container->get_split_offset() == 20);1101CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));1102}1103}11041105SUBCASE("[SplitContainer] Keep split offset when removing children") {1106SUBCASE("[SplitContainer] No expand flags") {1107int def_pos = 0;1108split_container->set_split_offset(100);11091110split_container->remove_child(child_a);1111MessageQueue::get_singleton()->flush();1112CHECK(split_container->get_split_offset() == 100);1113CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11141115split_container->remove_child(child_b);1116MessageQueue::get_singleton()->flush();1117CHECK(split_container->get_split_offset() == 100);11181119split_container->add_child(child_a);1120MessageQueue::get_singleton()->flush();1121CHECK(split_container->get_split_offset() == 100);1122CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11231124split_container->add_child(child_b);1125MessageQueue::get_singleton()->flush();1126CHECK(split_container->get_split_offset() == 100);1127CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1128}11291130SUBCASE("[SplitContainer] First child expanded") {1131int def_pos = split_container->get_size().x - sep.x;1132child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1133MessageQueue::get_singleton()->flush();1134split_container->set_split_offset(-100);11351136split_container->remove_child(child_a);1137MessageQueue::get_singleton()->flush();1138CHECK(split_container->get_split_offset() == -100);1139CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11401141split_container->remove_child(child_b);1142MessageQueue::get_singleton()->flush();1143CHECK(split_container->get_split_offset() == -100);11441145split_container->add_child(child_a);1146MessageQueue::get_singleton()->flush();1147CHECK(split_container->get_split_offset() == -100);1148CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11491150split_container->add_child(child_b);1151MessageQueue::get_singleton()->flush();1152CHECK(split_container->get_split_offset() == -100);1153CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));1154}11551156SUBCASE("[SplitContainer] Second child expanded") {1157int def_pos = 0;1158child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1159MessageQueue::get_singleton()->flush();1160split_container->set_split_offset(100);11611162split_container->remove_child(child_a);1163MessageQueue::get_singleton()->flush();1164CHECK(split_container->get_split_offset() == 100);1165CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11661167split_container->remove_child(child_b);1168MessageQueue::get_singleton()->flush();1169CHECK(split_container->get_split_offset() == 100);11701171split_container->add_child(child_a);1172MessageQueue::get_singleton()->flush();1173CHECK(split_container->get_split_offset() == 100);1174CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11751176split_container->add_child(child_b);1177MessageQueue::get_singleton()->flush();1178CHECK(split_container->get_split_offset() == 100);1179CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1180}11811182SUBCASE("[SplitContainer] Both children expanded") {1183int def_pos = (split_container->get_size().x - sep.x) / 2;1184child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1185child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1186MessageQueue::get_singleton()->flush();1187split_container->set_split_offset(20);11881189split_container->remove_child(child_a);1190MessageQueue::get_singleton()->flush();1191CHECK(split_container->get_split_offset() == 20);1192CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));11931194split_container->remove_child(child_b);1195MessageQueue::get_singleton()->flush();1196CHECK(split_container->get_split_offset() == 20);11971198split_container->add_child(child_a);1199MessageQueue::get_singleton()->flush();1200CHECK(split_container->get_split_offset() == 20);1201CHECK_RECTS(get_rects_multi(split_container, Vector<int>(), sep.x), get_child_rects(split_container));12021203split_container->add_child(child_b);1204MessageQueue::get_singleton()->flush();1205CHECK(split_container->get_split_offset() == 20);1206CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));1207}1208}12091210SUBCASE("[SplitContainer] Keep split offset when changing expand flags") {1211int def_pos = 0;1212split_container->set_split_offset(20);1213MessageQueue::get_singleton()->flush();1214CHECK(split_container->get_split_offset() == 20);1215CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));12161217child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1218def_pos = split_container->get_size().x - sep.x;1219MessageQueue::get_singleton()->flush();1220CHECK(split_container->get_split_offset() == 20);1221CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));12221223child_a->set_h_size_flags(Control::SIZE_FILL);1224child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1225def_pos = 0;1226MessageQueue::get_singleton()->flush();1227CHECK(split_container->get_split_offset() == 20);1228CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));12291230child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1231child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1232def_pos = (split_container->get_size().x - sep.x) / 2;1233MessageQueue::get_singleton()->flush();1234CHECK(split_container->get_split_offset() == 20);1235CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));12361237child_a->set_h_size_flags(Control::SIZE_FILL);1238child_b->set_h_size_flags(Control::SIZE_FILL);1239def_pos = 0;1240MessageQueue::get_singleton()->flush();1241CHECK(split_container->get_split_offset() == 20);1242CHECK_RECTS(get_rects(split_container, def_pos + 20, sep.x), get_child_rects(split_container));1243}12441245SUBCASE("[SplitContainer] Keep split offset when moving children") {1246int def_pos = 0;1247split_container->set_split_offset(100);12481249split_container->move_child(child_a, 1);1250MessageQueue::get_singleton()->flush();1251CHECK(split_container->get_split_offset() == 100);1252CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1253}12541255SUBCASE("[SplitContainer] Resize split container") {1256SUBCASE("[SplitContainer] No expand flags") {1257int def_pos = 0;1258// Increase the size.1259split_container->set_size(Size2(600, 500));1260MessageQueue::get_singleton()->flush();1261CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));12621263// Decrease the size.1264split_container->set_size(Size2(400, 500));1265MessageQueue::get_singleton()->flush();1266CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));12671268// Change size with a split offset.1269split_container->set_split_offset(100);1270MessageQueue::get_singleton()->flush();1271CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));12721273split_container->set_size(Size2(500, 500));1274MessageQueue::get_singleton()->flush();1275CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1276CHECK(split_container->get_split_offset() == 100);12771278// Change size so that the first child changes size.1279split_container->set_size(Size2(80, 500));1280MessageQueue::get_singleton()->flush();1281CHECK_RECTS(get_rects(split_container, 80 - sep.x, sep.x), get_child_rects(split_container));1282CHECK(split_container->get_split_offset() == 100);12831284// Increase size again.1285split_container->set_size(Size2(500, 500));1286MessageQueue::get_singleton()->flush();1287CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1288CHECK(split_container->get_split_offset() == 100);1289}12901291SUBCASE("[SplitContainer] First child expanded") {1292int def_pos = split_container->get_size().x - sep.x;1293child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1294MessageQueue::get_singleton()->flush();12951296// Increase the size.1297split_container->set_size(Size2(600, 500));1298def_pos = split_container->get_size().x - sep.x;1299MessageQueue::get_singleton()->flush();1300CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13011302// Decrease the size.1303split_container->set_size(Size2(400, 500));1304def_pos = split_container->get_size().x - sep.x;1305MessageQueue::get_singleton()->flush();1306CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13071308// Change size with a split offset.1309split_container->set_split_offset(-100);1310MessageQueue::get_singleton()->flush();1311CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));13121313split_container->set_size(Size2(500, 500));1314def_pos = split_container->get_size().x - sep.x;1315MessageQueue::get_singleton()->flush();1316CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));1317CHECK(split_container->get_split_offset() == -100);13181319// Change size so that the second child changes size.1320split_container->set_size(Size2(80, 500));1321MessageQueue::get_singleton()->flush();1322CHECK_RECTS(get_rects(split_container, 0, sep.x), get_child_rects(split_container));1323CHECK(split_container->get_split_offset() == -100);13241325// Increase size again.1326split_container->set_size(Size2(500, 500));1327MessageQueue::get_singleton()->flush();1328CHECK_RECTS(get_rects(split_container, def_pos - 100, sep.x), get_child_rects(split_container));1329CHECK(split_container->get_split_offset() == -100);1330}13311332SUBCASE("[SplitContainer] Second child expanded") {1333int def_pos = 0;1334child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1335MessageQueue::get_singleton()->flush();13361337// Increase the size.1338split_container->set_size(Size2(600, 500));1339MessageQueue::get_singleton()->flush();1340CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13411342// Decrease the size.1343split_container->set_size(Size2(400, 500));1344MessageQueue::get_singleton()->flush();1345CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13461347// Change size with a split offset.1348split_container->set_split_offset(100);1349MessageQueue::get_singleton()->flush();1350CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));13511352split_container->set_size(Size2(500, 500));1353MessageQueue::get_singleton()->flush();1354CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1355CHECK(split_container->get_split_offset() == 100);13561357// Change size so that the first child changes size.1358split_container->set_size(Size2(80, 500));1359MessageQueue::get_singleton()->flush();1360CHECK_RECTS(get_rects(split_container, 80 - sep.x, sep.x), get_child_rects(split_container));1361CHECK(split_container->get_split_offset() == 100);13621363// Increase size again.1364split_container->set_size(Size2(500, 500));1365MessageQueue::get_singleton()->flush();1366CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1367CHECK(split_container->get_split_offset() == 100);1368}13691370SUBCASE("[SplitContainer] Both children expanded") {1371int def_pos = (split_container->get_size().x - sep.x) / 2;1372child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1373child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1374MessageQueue::get_singleton()->flush();13751376// Increase the size.1377split_container->set_size(Size2(600, 500));1378def_pos = (split_container->get_size().x - sep.x) / 2;1379MessageQueue::get_singleton()->flush();1380CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13811382// Decrease the size.1383split_container->set_size(Size2(400, 500));1384def_pos = (split_container->get_size().x - sep.x) / 2;1385MessageQueue::get_singleton()->flush();1386CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));13871388// Change size with a split offset.1389split_container->set_split_offset(100);1390MessageQueue::get_singleton()->flush();1391CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));13921393split_container->set_size(Size2(500, 500));1394def_pos = (split_container->get_size().x - sep.x) / 2;1395MessageQueue::get_singleton()->flush();1396CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1397CHECK(split_container->get_split_offset() == 100);13981399// Change size so that the second child is minimized.1400split_container->set_size(Size2(80, 500));1401MessageQueue::get_singleton()->flush();1402CHECK_RECTS(get_rects(split_container, 80 - sep.x, sep.x), get_child_rects(split_container));1403CHECK(split_container->get_split_offset() == 100);14041405// Increase size again.1406split_container->set_size(Size2(500, 500));1407def_pos = (split_container->get_size().x - sep.x) / 2;1408MessageQueue::get_singleton()->flush();1409CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1410CHECK(split_container->get_split_offset() == 100);1411}14121413SUBCASE("[SplitContainer] Unequal stretch ratios") {1414int def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;1415child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1416child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1417child_a->set_stretch_ratio(2.0);1418MessageQueue::get_singleton()->flush();14191420// Increase the size.1421split_container->set_size(Size2(600, 500));1422def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;1423MessageQueue::get_singleton()->flush();1424CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));14251426// Decrease the size.1427split_container->set_size(Size2(400, 500));1428def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;1429MessageQueue::get_singleton()->flush();1430CHECK_RECTS(get_rects(split_container, def_pos, sep.x), get_child_rects(split_container));14311432// Change size with a split offset.1433split_container->set_split_offset(100);1434MessageQueue::get_singleton()->flush();1435CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));14361437split_container->set_size(Size2(500, 500));1438def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;1439MessageQueue::get_singleton()->flush();1440CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1441CHECK(split_container->get_split_offset() == 100);14421443// Change size so that the second child is minimized.1444split_container->set_size(Size2(80, 500));1445MessageQueue::get_singleton()->flush();1446CHECK_RECTS(get_rects(split_container, 80 - sep.x, sep.x), get_child_rects(split_container));1447CHECK(split_container->get_split_offset() == 100);14481449// Increase size again.1450split_container->set_size(Size2(500, 500));1451def_pos = (split_container->get_size().x * 2 / 3) - sep.x / 2;1452MessageQueue::get_singleton()->flush();1453CHECK_RECTS(get_rects(split_container, def_pos + 100, sep.x), get_child_rects(split_container));1454CHECK(split_container->get_split_offset() == 100);1455}1456}14571458SUBCASE("[SplitContainer] Drag") {1459SUBCASE("[SplitContainer] Vertical, no expand flags") {1460SIGNAL_WATCH(split_container, "dragged");1461Array signal_args = { { 0 } };14621463split_container->set_vertical(true);1464Point2 mouse_offset = Point2(1, 1);1465int dragger_pos = 0;1466int split_dragger_ofs = 0;14671468// Grab the dragger.1469SEND_GUI_MOUSE_BUTTON_EVENT(mouse_offset + Point2(0, dragger_pos), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);1470MessageQueue::get_singleton()->flush();1471CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1472CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1473SIGNAL_CHECK_FALSE("dragged");14741475// Move the dragger.1476dragger_pos = 10;1477SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(0, dragger_pos), MouseButtonMask::LEFT, Key::NONE);1478MessageQueue::get_singleton()->flush();1479CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1480CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1481// It is clamped.1482split_container->clamp_split_offset();1483CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1484((Array)signal_args[0])[0] = split_container->get_split_offset();1485SIGNAL_CHECK("dragged", signal_args);14861487// Move down.1488dragger_pos = 400;1489SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(0, dragger_pos), MouseButtonMask::LEFT, Key::NONE);1490MessageQueue::get_singleton()->flush();1491CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1492CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1493((Array)signal_args[0])[0] = split_container->get_split_offset();1494SIGNAL_CHECK("dragged", signal_args);14951496// Moves even when mouse is outside.1497dragger_pos = split_container->get_size().y - sep.y;1498SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(0, 1000), MouseButtonMask::LEFT, Key::NONE);1499MessageQueue::get_singleton()->flush();1500CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1501CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1502((Array)signal_args[0])[0] = split_container->get_split_offset();1503SIGNAL_CHECK("dragged", signal_args);15041505// Move up.1506dragger_pos = 100;1507SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(0, dragger_pos), MouseButtonMask::LEFT, Key::NONE);1508MessageQueue::get_singleton()->flush();1509CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1510CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1511((Array)signal_args[0])[0] = split_container->get_split_offset();1512SIGNAL_CHECK("dragged", signal_args);15131514// Release.1515SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(mouse_offset + Point2(0, dragger_pos), MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);1516MessageQueue::get_singleton()->flush();1517CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1518CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1519SIGNAL_CHECK_FALSE("dragged");15201521// No longer moves with the mouse.1522SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(0, 200), MouseButtonMask::NONE, Key::NONE);1523MessageQueue::get_singleton()->flush();1524CHECK_RECTS(get_rects(split_container, dragger_pos, sep.y, false), get_child_rects(split_container));1525CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1526SIGNAL_CHECK_FALSE("dragged");15271528SIGNAL_UNWATCH(split_container, "dragged");1529}15301531SUBCASE("[SplitContainer] No expand flags") {1532Point2 mouse_offset = Point2(1, 1);1533int dragger_pos = 0;1534int split_dragger_ofs = 0;15351536// Grab the dragger.1537SEND_GUI_MOUSE_BUTTON_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);1538MessageQueue::get_singleton()->flush();1539CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1540CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15411542// Move the dragger.1543dragger_pos = 10;1544SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1545MessageQueue::get_singleton()->flush();1546CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1547CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1548// It is clamped.1549split_container->clamp_split_offset();1550CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15511552// Continue moving.1553dragger_pos = 400;1554SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1555MessageQueue::get_singleton()->flush();1556CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1557CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15581559// Moves even when mouse is outside.1560dragger_pos = split_container->get_size().x - sep.x;1561SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(1000, 0), MouseButtonMask::LEFT, Key::NONE);1562MessageQueue::get_singleton()->flush();1563CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1564CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15651566// Move back in.1567dragger_pos = 100;1568SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1569MessageQueue::get_singleton()->flush();1570CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1571CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15721573// Release.1574SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);1575MessageQueue::get_singleton()->flush();1576CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1577CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15781579// No longer moves with the mouse.1580SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(200, 0), MouseButtonMask::NONE, Key::NONE);1581MessageQueue::get_singleton()->flush();1582CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1583CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1584}15851586SUBCASE("[SplitContainer] First child expanded") {1587child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1588MessageQueue::get_singleton()->flush();1589Point2 mouse_offset = Point2(1, 1);1590int dragger_pos = split_container->get_size().x - sep.x;1591int split_dragger_ofs = -dragger_pos;15921593// Grab the dragger.1594SEND_GUI_MOUSE_BUTTON_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);1595MessageQueue::get_singleton()->flush();1596CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1597CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);15981599// Move the dragger.1600dragger_pos -= 10;1601SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1602MessageQueue::get_singleton()->flush();1603CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1604CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1605// It is clamped.1606split_container->clamp_split_offset();1607CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16081609// Continue moving.1610dragger_pos = 400;1611SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1612MessageQueue::get_singleton()->flush();1613CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1614CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16151616// Moves even when mouse is outside.1617dragger_pos = split_container->get_size().x - sep.x;1618SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(1000, 0), MouseButtonMask::LEFT, Key::NONE);1619MessageQueue::get_singleton()->flush();1620CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1621CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16221623// Move back in.1624dragger_pos = 100;1625SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1626MessageQueue::get_singleton()->flush();1627CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1628CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16291630// Release.1631SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);1632MessageQueue::get_singleton()->flush();1633CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1634CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16351636// No longer moves with the mouse.1637SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(200, 0), MouseButtonMask::NONE, Key::NONE);1638MessageQueue::get_singleton()->flush();1639CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1640CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1641}16421643SUBCASE("[SplitContainer] Second child expanded") {1644child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1645MessageQueue::get_singleton()->flush();1646Point2 mouse_offset = Point2(1, 1);1647int dragger_pos = 0;1648int split_dragger_ofs = 0;16491650// Grab the dragger.1651SEND_GUI_MOUSE_BUTTON_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);1652MessageQueue::get_singleton()->flush();1653CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1654CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16551656// Move the dragger.1657dragger_pos = 10;1658SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1659MessageQueue::get_singleton()->flush();1660CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1661CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1662// It is clamped.1663split_container->clamp_split_offset();1664CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16651666// Continue moving.1667dragger_pos = 400;1668SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1669MessageQueue::get_singleton()->flush();1670CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1671CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16721673// Moves even when mouse is outside.1674dragger_pos = split_container->get_size().x - sep.x;1675SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(1000, 0), MouseButtonMask::LEFT, Key::NONE);1676MessageQueue::get_singleton()->flush();1677CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1678CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16791680// Move back in.1681dragger_pos = 100;1682SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1683MessageQueue::get_singleton()->flush();1684CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1685CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16861687// Release.1688SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);1689MessageQueue::get_singleton()->flush();1690CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1691CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);16921693// No longer moves with the mouse.1694SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(200, 0), MouseButtonMask::NONE, Key::NONE);1695MessageQueue::get_singleton()->flush();1696CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1697CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1698}16991700SUBCASE("[SplitContainer] Both children expanded") {1701child_a->set_h_size_flags(Control::SIZE_EXPAND_FILL);1702child_b->set_h_size_flags(Control::SIZE_EXPAND_FILL);1703MessageQueue::get_singleton()->flush();1704Point2 mouse_offset = Point2(1, 1);1705int dragger_pos = (split_container->get_size().x - sep.x) / 2;1706int split_dragger_ofs = -dragger_pos;17071708// Grab the dragger.1709SEND_GUI_MOUSE_BUTTON_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);1710MessageQueue::get_singleton()->flush();1711CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1712CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17131714// Move the dragger.1715dragger_pos += 10;1716SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1717MessageQueue::get_singleton()->flush();1718CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1719CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1720// It is clamped.1721split_container->clamp_split_offset();1722CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17231724// Continue moving.1725dragger_pos = 400;1726SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1727MessageQueue::get_singleton()->flush();1728CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1729CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17301731// Moves even when mouse is outside.1732dragger_pos = split_container->get_size().x - sep.x;1733SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(1000, 0), MouseButtonMask::LEFT, Key::NONE);1734MessageQueue::get_singleton()->flush();1735CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1736CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17371738// Move back in.1739dragger_pos = 100;1740SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButtonMask::LEFT, Key::NONE);1741MessageQueue::get_singleton()->flush();1742CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1743CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17441745// Release.1746SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(mouse_offset + Point2(dragger_pos, 0), MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);1747MessageQueue::get_singleton()->flush();1748CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1749CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);17501751// No longer moves with the mouse.1752SEND_GUI_MOUSE_MOTION_EVENT(mouse_offset + Point2(200, 0), MouseButtonMask::NONE, Key::NONE);1753MessageQueue::get_singleton()->flush();1754CHECK_RECTS(get_rects(split_container, dragger_pos, sep.x), get_child_rects(split_container));1755CHECK(split_container->get_split_offset() == dragger_pos + split_dragger_ofs);1756}1757}17581759memdelete(child_b);1760memdelete(child_a);1761memdelete(split_container);1762}17631764TEST_CASE("[SceneTree][SplitContainer] More children") {1765SplitContainer *split_container = memnew(SplitContainer);1766split_container->set_size(Size2(500, 500));1767SceneTree::get_singleton()->get_root()->add_child(split_container);1768Control *child_a = memnew(Control);1769Control *child_b = memnew(Control);1770Control *child_c = memnew(Control);1771split_container->add_child(child_a);1772split_container->add_child(child_b);1773split_container->add_child(child_c);1774Size2i min_size = Size2i(10, 10);1775child_a->set_custom_minimum_size(min_size);1776child_b->set_custom_minimum_size(min_size);1777child_c->set_custom_minimum_size(min_size);1778MessageQueue::get_singleton()->flush();17791780const int sep_constant = split_container->get_theme_constant("separation");1781const Size2i sep = Size2i(MAX(sep_constant, split_container->get_theme_icon("h_grabber")->get_width()), MAX(sep_constant, split_container->get_theme_icon("v_grabber")->get_height()));17821783SUBCASE("[SplitContainer] Duplicate") {1784// Make sure dynamically added internal draggers duplicate properly.1785SplitContainer *duplicate = (SplitContainer *)(Node *)split_container->duplicate();1786MessageQueue::get_singleton()->flush();1787CHECK(duplicate->get_child_count(false) == split_container->get_child_count(false));1788CHECK(duplicate->get_child_count(true) == split_container->get_child_count(true));1789memdelete(duplicate);1790}17911792SUBCASE("[SplitContainer] Default position") {1793CHECK(split_container->get_split_offsets() == Vector<int>({ 0, 0 }));17941795set_size_flags(split_container, { -1, -1, -1 }); // None expanded.1796Vector<int> def_pos = { min_size.x, min_size.x * 2 + sep.x };1797CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1798split_container->clamp_split_offset();1799MessageQueue::get_singleton()->flush();1800CHECK(split_container->get_split_offsets() == Vector<int>({ min_size.x, min_size.x * 2 + sep.x }));1801CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));18021803split_container->set_split_offsets({ 0, 0 });18041805set_size_flags(split_container, { 1, -1, -1 }); // First expanded.1806def_pos = { (int)split_container->get_size().x - sep.x * 2 - min_size.x * 2, (int)split_container->get_size().x - sep.x - min_size.x };1807CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1808split_container->clamp_split_offset();1809MessageQueue::get_singleton()->flush();1810CHECK(split_container->get_split_offsets() == Vector<int>({ -min_size.x * 2 - sep.x, -min_size.x }));1811CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1812split_container->set_split_offsets({ 0, 0 });18131814set_size_flags(split_container, { -1, 1, -1 }); // Second expanded.1815def_pos = { min_size.x, (int)split_container->get_size().x - min_size.x - sep.x };1816CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1817split_container->clamp_split_offset();1818MessageQueue::get_singleton()->flush();1819CHECK(split_container->get_split_offsets() == Vector<int>({ min_size.x, -min_size.x }));1820CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1821split_container->set_split_offsets({ 0, 0 });18221823set_size_flags(split_container, { -1, -1, 1 }); // Third expanded.1824def_pos = { min_size.x, min_size.x * 2 + sep.x };1825CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1826split_container->clamp_split_offset();1827MessageQueue::get_singleton()->flush();1828CHECK(split_container->get_split_offsets() == Vector<int>({ min_size.x, min_size.x * 2 + sep.x }));1829CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1830split_container->set_split_offsets({ 0, 0 });18311832set_size_flags(split_container, { 1, 1, -1 }); // First and second expanded.1833int child_2_expanded_size = ((int)split_container->get_size().x - min_size.x) / 2 - sep.x;1834def_pos = { child_2_expanded_size, (int)split_container->get_size().x - min_size.x - sep.x };1835CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1836split_container->clamp_split_offset();1837MessageQueue::get_singleton()->flush();1838CHECK(split_container->get_split_offsets() == Vector<int>({ 0, -min_size.x }));1839CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1840split_container->set_split_offsets({ 0, 0 });18411842set_size_flags(split_container, { 1, -1, 1 }); // First and third expanded.1843def_pos = { child_2_expanded_size, child_2_expanded_size + min_size.x + sep.x };1844CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1845split_container->clamp_split_offset();1846MessageQueue::get_singleton()->flush();1847CHECK(split_container->get_split_offsets() == Vector<int>({ 0, 0 }));1848CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1849split_container->set_split_offsets({ 0, 0 });18501851set_size_flags(split_container, { -1, 1, 1 }); // Second and third expanded.1852def_pos = { min_size.x, min_size.x + child_2_expanded_size + sep.x };1853CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1854split_container->clamp_split_offset();1855MessageQueue::get_singleton()->flush();1856CHECK(split_container->get_split_offsets() == Vector<int>({ min_size.x, 0 }));1857CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1858split_container->set_split_offsets({ 0, 0 });18591860set_size_flags(split_container, { 1, 1, 1 }); // All expanded.1861int child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;1862// Add 1 due to pixel error accumulation.1863def_pos = { child_3_expanded_size, child_3_expanded_size * 2 + sep.x + 1 };1864CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1865split_container->clamp_split_offset();1866MessageQueue::get_singleton()->flush();1867CHECK(split_container->get_split_offsets() == Vector<int>({ 0, 0 }));1868CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1869split_container->set_split_offsets({ 0, 0 });18701871set_size_flags(split_container, { 1, 2, 3 }); // All expanded, different ratios.1872int child_6_expanded_size = (split_container->get_size().x - sep.x * 2) / 6;1873def_pos = { child_6_expanded_size, child_6_expanded_size * 3 + sep.x + 1 };1874CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1875split_container->clamp_split_offset();1876MessageQueue::get_singleton()->flush();1877CHECK(split_container->get_split_offsets() == Vector<int>({ 0, 0 }));1878CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));1879split_container->set_split_offsets({ 0, 0 });1880}18811882SUBCASE("[SplitContainer] Set split offset") {1883const int expanded_single_size = (int)split_container->get_size().x - min_size.x * 2 - sep.x * 2;18841885SUBCASE("[SplitContainer] No expand flags") {1886set_size_flags(split_container, { -1, -1, -1 }); // None expanded.18871888// First is positive.1889split_container->set_split_offsets({ 50, 0 });1890MessageQueue::get_singleton()->flush();1891CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 0 });1892CHECK_RECTS(get_rects_multi(split_container, { 50, 50 + min_size.x + sep.x }, sep.x), get_child_rects(split_container));18931894// Second is positive.1895split_container->set_split_offsets({ 0, 50 });1896MessageQueue::get_singleton()->flush();1897CHECK(split_container->get_split_offsets() == Vector<int>{ 0, 50 });1898CHECK_RECTS(get_rects_multi(split_container, { min_size.x, 50 }, sep.x), get_child_rects(split_container));18991900// Both are positive and equal, the first will override since they both start at 0.1901split_container->set_split_offsets({ 50, 50 });1902MessageQueue::get_singleton()->flush();1903CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 50 });1904CHECK_RECTS(get_rects_multi(split_container, { 50, 50 + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19051906// Both are negative and clamped.1907split_container->set_split_offsets({ -50, -50 });1908MessageQueue::get_singleton()->flush();1909CHECK(split_container->get_split_offsets() == Vector<int>{ -50, -50 });1910CHECK_RECTS(get_rects_multi(split_container, { min_size.x, min_size.x * 2 + sep.x }, sep.x), get_child_rects(split_container));19111912// First positive, second negative. First takes priority.1913split_container->set_split_offsets({ 50, -50 });1914MessageQueue::get_singleton()->flush();1915CHECK(split_container->get_split_offsets() == Vector<int>{ 50, -50 });1916CHECK_RECTS(get_rects_multi(split_container, { 50, 50 + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19171918// First is clamped and pushes second to the end.1919split_container->set_split_offsets({ 1000, 0 });1920MessageQueue::get_singleton()->flush();1921CHECK(split_container->get_split_offsets() == Vector<int>{ 1000, 0 });1922CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19231924// Second is clamped.1925split_container->set_split_offsets({ 0, 1000 });1926MessageQueue::get_singleton()->flush();1927CHECK(split_container->get_split_offsets() == Vector<int>{ 0, 1000 });1928CHECK_RECTS(get_rects_multi(split_container, { min_size.x, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19291930// Both are clamped positively, first one takes priority.1931split_container->set_split_offsets({ 1000, 1000 });1932MessageQueue::get_singleton()->flush();1933CHECK(split_container->get_split_offsets() == Vector<int>{ 1000, 1000 });1934CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));1935}19361937SUBCASE("[SplitContainer] First child expanded") {1938set_size_flags(split_container, { 1, -1, -1 }); // First expanded.19391940// First is positive and clamped.1941split_container->set_split_offsets({ 50, 0 });1942MessageQueue::get_singleton()->flush();1943CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 0 });1944CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19451946// Second is positive and clamped.1947split_container->set_split_offsets({ 0, 50 });1948MessageQueue::get_singleton()->flush();1949CHECK(split_container->get_split_offsets() == Vector<int>{ 0, 50 });1950CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19511952// First is negative and moves left.1953split_container->set_split_offsets({ -50, 0 });1954MessageQueue::get_singleton()->flush();1955CHECK(split_container->get_split_offsets() == Vector<int>{ -50, 0 });1956CHECK_RECTS(get_rects_multi(split_container, { (int)split_container->get_size().x - 50 - sep.x, (int)split_container->get_size().x - min_size.x - sep.x }, sep.x), get_child_rects(split_container));19571958// Second is negative, but first has priority so it doesn't move.1959split_container->set_split_offsets({ 0, -50 });1960MessageQueue::get_singleton()->flush();1961CHECK(split_container->get_split_offsets() == Vector<int>{ 0, -50 });1962CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19631964// Both are negative and equal, they move left but the second doesn't move as much as wanted.1965split_container->set_split_offsets({ -50, -50 });1966MessageQueue::get_singleton()->flush();1967CHECK(split_container->get_split_offsets() == Vector<int>{ -50, -50 });1968CHECK_RECTS(get_rects_multi(split_container, { (int)split_container->get_size().x - 50 - sep.x, (int)split_container->get_size().x - 50 + min_size.x }, sep.x), get_child_rects(split_container));19691970// Both are negative with space and move left.1971split_container->set_split_offsets({ -100, -50 });1972MessageQueue::get_singleton()->flush();1973CHECK(split_container->get_split_offsets() == Vector<int>{ -100, -50 });1974CHECK_RECTS(get_rects_multi(split_container, { (int)split_container->get_size().x - 100 - sep.x, (int)split_container->get_size().x - 50 - sep.x }, sep.x), get_child_rects(split_container));19751976// First moves all the way left.1977split_container->set_split_offsets({ -1000, 0 });1978MessageQueue::get_singleton()->flush();1979CHECK(split_container->get_split_offsets() == Vector<int>{ -1000, 0 });1980CHECK_RECTS(get_rects_multi(split_container, { min_size.x, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19811982// Second cannot move all the way left since first takes priority.1983split_container->set_split_offsets({ 0, -1000 });1984MessageQueue::get_singleton()->flush();1985CHECK(split_container->get_split_offsets() == Vector<int>{ 0, -1000 });1986CHECK_RECTS(get_rects_multi(split_container, { expanded_single_size, expanded_single_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));19871988// First and second move all the way left.1989split_container->set_split_offsets({ -1000, -1000 });1990MessageQueue::get_singleton()->flush();1991CHECK(split_container->get_split_offsets() == Vector<int>{ -1000, -1000 });1992CHECK_RECTS(get_rects_multi(split_container, { min_size.x, min_size.x * 2 + sep.x }, sep.x), get_child_rects(split_container));1993}19941995SUBCASE("[SplitContainer] All children expanded") {1996set_size_flags(split_container, { 1, 1, 1 }); // All expanded.1997const int child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;19981999// First is moved positive, does not affect second.2000split_container->set_split_offsets({ 50, 0 });2001MessageQueue::get_singleton()->flush();2002CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 0 });2003CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size + 50, child_3_expanded_size * 2 + sep.x + 1 }, sep.x), get_child_rects(split_container));20042005// First is moved negative, does not affect second.2006split_container->set_split_offsets({ -50, 0 });2007MessageQueue::get_singleton()->flush();2008CHECK(split_container->get_split_offsets() == Vector<int>{ -50, 0 });2009CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size - 50, child_3_expanded_size * 2 + sep.x + 1 }, sep.x), get_child_rects(split_container));20102011// Second is moved positive, does not affect first.2012split_container->set_split_offsets({ 0, 50 });2013MessageQueue::get_singleton()->flush();2014CHECK(split_container->get_split_offsets() == Vector<int>{ 0, 50 });2015CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size, child_3_expanded_size * 2 + 50 + sep.x + 1 }, sep.x), get_child_rects(split_container));20162017// Second is moved negative, does not affect first.2018split_container->set_split_offsets({ 0, -50 });2019MessageQueue::get_singleton()->flush();2020CHECK(split_container->get_split_offsets() == Vector<int>{ 0, -50 });2021CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size, child_3_expanded_size * 2 - 50 + sep.x + 1 }, sep.x), get_child_rects(split_container));20222023// First is moved positive enough to affect second.2024split_container->set_split_offsets({ 200, 0 });2025MessageQueue::get_singleton()->flush();2026CHECK(split_container->get_split_offsets() == Vector<int>{ 200, 0 });2027CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size + 200, child_3_expanded_size + 200 + sep.x + min_size.x }, sep.x), get_child_rects(split_container));20282029// Second is moved enough to pass the first, but the first has priority.2030split_container->set_split_offsets({ 0, -200 });2031MessageQueue::get_singleton()->flush();2032CHECK(split_container->get_split_offsets() == Vector<int>{ 0, -200 });2033CHECK_RECTS(get_rects_multi(split_container, { child_3_expanded_size, child_3_expanded_size + min_size.x + sep.x }, sep.x), get_child_rects(split_container));2034}2035}20362037SUBCASE("[SplitContainer] Resize") {2038SUBCASE("[SplitContainer] No expand flags") {2039Vector<int> def_pos = { min_size.x, min_size.x * 2 + sep.x };2040// Increase the size.2041split_container->set_size(Size2(600, 500));2042MessageQueue::get_singleton()->flush();2043CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));20442045// Decrease the size.2046split_container->set_size(Size2(400, 500));2047MessageQueue::get_singleton()->flush();2048CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));20492050// Change size with a split offset.2051split_container->set_split_offsets({ 50, 100 });2052split_container->set_size(Size2(500, 500));2053MessageQueue::get_singleton()->flush();2054CHECK_RECTS(get_rects_multi(split_container, { 50, 100 }, sep.x), get_child_rects(split_container));2055CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 100 });20562057// Change size so that the second child gets clamped and changes size.2058split_container->set_size(Size2(100, 500));2059MessageQueue::get_singleton()->flush();2060CHECK_RECTS(get_rects_multi(split_container, { 50, 100 - sep.x - min_size.x }, sep.x), get_child_rects(split_container));2061CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 100 });20622063// Change size so that the first child changes size.2064split_container->set_size(Size2(60, 500));2065MessageQueue::get_singleton()->flush();2066CHECK_RECTS(get_rects_multi(split_container, { 60 - min_size.x * 2 - sep.x * 2, 60 - sep.x - min_size.x }, sep.x), get_child_rects(split_container));2067CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 100 });20682069// Increase size again.2070split_container->set_size(Size2(500, 500));2071MessageQueue::get_singleton()->flush();2072CHECK_RECTS(get_rects_multi(split_container, { 50, 100 }, sep.x), get_child_rects(split_container));2073CHECK(split_container->get_split_offsets() == Vector<int>{ 50, 100 });2074}20752076SUBCASE("[SplitContainer] First child expanded") {2077set_size_flags(split_container, { 1, -1, -1 });2078Vector<int> def_pos = { (int)split_container->get_size().x - sep.x * 2 - min_size.x, (int)split_container->get_size().x - sep.x };2079// Increase the size.2080split_container->set_size(Size2(600, 500));2081def_pos = { (int)split_container->get_size().x - sep.x * 2 - min_size.x * 2, (int)split_container->get_size().x - sep.x - min_size.x };2082MessageQueue::get_singleton()->flush();2083CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));20842085// Decrease the size.2086split_container->set_size(Size2(400, 500));2087def_pos = { (int)split_container->get_size().x - sep.x * 2 - min_size.x * 2, (int)split_container->get_size().x - sep.x - min_size.x };2088MessageQueue::get_singleton()->flush();2089CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));20902091// Change size with a split offset.2092split_container->set_split_offsets({ -100, -50 });2093split_container->set_size(Size2(500, 500));2094MessageQueue::get_singleton()->flush();2095CHECK_RECTS(get_rects_multi(split_container, { (int)split_container->get_size().x - 100 - sep.x, (int)split_container->get_size().x - 50 - sep.x }, sep.x), get_child_rects(split_container));2096CHECK(split_container->get_split_offsets() == Vector<int>{ -100, -50 });20972098// Change size so that the first child gets clamped and changes size.2099split_container->set_size(Size2(100, 500));2100MessageQueue::get_singleton()->flush();2101CHECK_RECTS(get_rects_multi(split_container, { min_size.x, (int)split_container->get_size().x - 50 - sep.x }, sep.x), get_child_rects(split_container));2102CHECK(split_container->get_split_offsets() == Vector<int>{ -100, -50 });21032104// Change size so that the second child changes size.2105split_container->set_size(Size2(50, 500));2106MessageQueue::get_singleton()->flush();2107CHECK_RECTS(get_rects_multi(split_container, { min_size.x, min_size.x * 2 + sep.x }, sep.x), get_child_rects(split_container));2108CHECK(split_container->get_split_offsets() == Vector<int>{ -100, -50 });21092110// Increase size again.2111split_container->set_size(Size2(500, 500));2112MessageQueue::get_singleton()->flush();2113CHECK_RECTS(get_rects_multi(split_container, { (int)split_container->get_size().x - 100 - sep.x, (int)split_container->get_size().x - 50 - sep.x }, sep.x), get_child_rects(split_container));2114CHECK(split_container->get_split_offsets() == Vector<int>{ -100, -50 });2115}21162117SUBCASE("[SplitContainer] All children expanded") {2118set_size_flags(split_container, { 1, 1, 1 });2119// Increase the size.2120split_container->set_size(Size2(600, 500));2121MessageQueue::get_singleton()->flush();2122int child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;2123Vector<int> def_pos = { child_3_expanded_size, child_3_expanded_size * 2 + sep.x };2124CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21252126// Decrease the size.2127split_container->set_size(Size2(400, 500));2128MessageQueue::get_singleton()->flush();2129child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;2130def_pos = { child_3_expanded_size, child_3_expanded_size * 2 + sep.x };2131CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21322133// Change size with a split offset.2134split_container->set_split_offsets({ -50, 50 });2135split_container->set_size(Size2(500, 500));2136MessageQueue::get_singleton()->flush();2137child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;2138def_pos = { child_3_expanded_size, child_3_expanded_size * 2 + sep.x + 1 };2139CHECK_RECTS(get_rects_multi(split_container, { def_pos[0] - 50, def_pos[1] + 50 }, sep.x), get_child_rects(split_container));2140CHECK(split_container->get_split_offsets() == Vector<int>{ -50, 50 });21412142// Change size so that the children get clamped and change sizes.2143split_container->set_size(Size2(100, 500));2144MessageQueue::get_singleton()->flush();2145CHECK_RECTS(get_rects_multi(split_container, { min_size.x, (int)split_container->get_size().x - sep.x - min_size.x }, sep.x), get_child_rects(split_container));2146CHECK(split_container->get_split_offsets() == Vector<int>{ -50, 50 });21472148// Increase size again.2149split_container->set_size(Size2(500, 500));2150MessageQueue::get_singleton()->flush();2151child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;2152def_pos = { child_3_expanded_size, child_3_expanded_size * 2 + sep.x + 1 };2153CHECK_RECTS(get_rects_multi(split_container, { def_pos[0] - 50, def_pos[1] + 50 }, sep.x), get_child_rects(split_container));2154CHECK(split_container->get_split_offsets() == Vector<int>{ -50, 50 });2155}2156}21572158SUBCASE("[SplitContainer] Visibility changes") {2159set_size_flags(split_container, { -1, -1, -1 }); // None expanded.2160split_container->set_split_offsets({ 50, 122 });2161MessageQueue::get_singleton()->flush();2162Vector<int> def_pos = { 50, 122 };2163CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21642165// Hide and show the first child.2166child_a->set_visible(false);2167MessageQueue::get_singleton()->flush();2168CHECK(split_container->get_split_offsets() == Vector<int>({ 60 }));2169CHECK_RECTS(get_rects_multi(split_container, { 60 }, sep.x), get_child_rects(split_container));21702171child_a->set_visible(true);2172MessageQueue::get_singleton()->flush();2173CHECK(split_container->get_split_offsets() == def_pos);2174CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21752176// Hide and show the second child.2177child_b->set_visible(false);2178MessageQueue::get_singleton()->flush();2179CHECK(split_container->get_split_offsets() == Vector<int>({ 50 }));2180CHECK_RECTS(get_rects_multi(split_container, { 50 }, sep.x), get_child_rects(split_container));2181child_b->set_visible(true);2182MessageQueue::get_singleton()->flush();2183CHECK(split_container->get_split_offsets() == def_pos);2184CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21852186// Hide and show the last child.2187child_c->set_visible(false);2188MessageQueue::get_singleton()->flush();2189CHECK(split_container->get_split_offsets() == Vector<int>({ 50 }));2190CHECK_RECTS(get_rects_multi(split_container, { 50 }, sep.x), get_child_rects(split_container));2191child_c->set_visible(true);2192MessageQueue::get_singleton()->flush();2193CHECK(split_container->get_split_offsets() == def_pos);2194CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));21952196set_size_flags(split_container, { 1, 1, 1 }); // All expanded.2197split_container->set_split_offsets({ 50, 60 });2198MessageQueue::get_singleton()->flush();2199int child_3_expanded_size = (split_container->get_size().x - sep.x * 2) / 3;2200def_pos = { child_3_expanded_size + 50, child_3_expanded_size * 2 + sep.x + 1 + 60 };2201CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));22022203// Hide and show the first child.2204int child_2_expanded_size = (split_container->get_size().x - sep.x) / 2;2205child_a->set_visible(false);2206MessageQueue::get_singleton()->flush();2207int half_point = (split_container->get_size().x - def_pos[0]) / 2 - sep.x;2208int so = child_3_expanded_size + 11 - half_point; // 11 is from 60 - 50 + 1 to get the second child's size.2209CHECK_RECTS(get_rects_multi(split_container, { child_2_expanded_size + so }, sep.x), get_child_rects(split_container));2210CHECK(split_container->get_split_offsets() == Vector<int>({ so }));2211child_a->set_visible(true);2212MessageQueue::get_singleton()->flush();2213CHECK_RECTS(get_rects_multi(split_container, def_pos, sep.x), get_child_rects(split_container));2214CHECK(split_container->get_split_offsets() == Vector<int>({ 50, 60 }));22152216// Hide and show the second child.2217child_b->set_visible(false);2218MessageQueue::get_singleton()->flush();2219half_point = (split_container->get_size().x - (def_pos[1] - def_pos[0] - sep.x)) / 2 - sep.x + 1;2220so = def_pos[0] - half_point;2221CHECK_RECTS(get_rects_multi(split_container, { child_2_expanded_size + so }, sep.x), get_child_rects(split_container));2222CHECK(split_container->get_split_offsets() == Vector<int>({ so }));2223child_b->set_visible(true);2224MessageQueue::get_singleton()->flush();2225// There is lost precision due to SplitContainer using ints, so this is off by one.2226CHECK_RECTS(get_rects_multi(split_container, { def_pos[0] - 1, def_pos[1] - 1 }, sep.x), get_child_rects(split_container));2227CHECK(split_container->get_split_offsets() == Vector<int>({ 49, 59 }));22282229// Hide and show the last child.2230split_container->set_split_offsets({ 50, 60 });2231child_c->set_visible(false);2232MessageQueue::get_singleton()->flush();2233half_point = (def_pos[1] - sep.x) / 2 + 1;2234so = def_pos[0] - half_point;2235CHECK_RECTS(get_rects_multi(split_container, { child_2_expanded_size + so }, sep.x), get_child_rects(split_container));2236CHECK(split_container->get_split_offsets() == Vector<int>({ so }));2237child_c->set_visible(true);2238MessageQueue::get_singleton()->flush();2239CHECK_RECTS(get_rects_multi(split_container, { def_pos[0] - 1, def_pos[1] - 1 }, sep.x), get_child_rects(split_container));2240CHECK(split_container->get_split_offsets() == Vector<int>({ 49, 59 }));2241}22422243SUBCASE("[SplitContainer] Adjust split offset when moving children") {2244split_container->set_split_offsets({ 50, 80 });2245split_container->move_child(child_a, 1);2246Vector<int> pos = { 30 - sep.x, 80 }; // 30 = 80 - 50.2247MessageQueue::get_singleton()->flush();2248CHECK(split_container->get_split_offsets() == pos);2249CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22502251// Move last child to first.2252split_container->set_split_offsets({ 50, 80 });2253split_container->move_child(child_c, 0);2254pos = { (int)split_container->get_size().x - 80 - sep.x, (int)split_container->get_size().x - 30 };2255MessageQueue::get_singleton()->flush();2256CHECK(split_container->get_split_offsets() == pos);2257CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22582259// Move it back.2260split_container->move_child(child_c, 2);2261pos = { 50, 80 };2262MessageQueue::get_singleton()->flush();2263CHECK(split_container->get_split_offsets() == pos);2264CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));2265}22662267SUBCASE("[SplitContainer] Showing child with not enough space shrinks the largest child first") {2268set_size_flags(split_container, { -1, -1, -1 }); // None expanded.22692270// Second child is largest.2271child_a->set_visible(false);2272Vector<int> pos = { 360 };2273split_container->set_split_offsets(pos);22742275MessageQueue::get_singleton()->flush();2276CHECK(split_container->get_split_offsets() == pos);2277CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22782279child_a->set_size(Vector2(100, 100));2280MessageQueue::get_singleton()->flush();2281CHECK(split_container->get_split_offsets() == pos);2282CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22832284child_a->set_visible(true);2285pos = { 100, 360 };2286MessageQueue::get_singleton()->flush();2287CHECK(split_container->get_split_offsets() == pos);2288CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22892290// Last child is largest.2291child_a->set_visible(false);2292pos = { 60 };2293split_container->set_split_offsets(pos);22942295MessageQueue::get_singleton()->flush();2296CHECK(split_container->get_split_offsets() == pos);2297CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));22982299child_a->set_size(Vector2(100, 100));2300MessageQueue::get_singleton()->flush();2301CHECK(split_container->get_split_offsets() == pos);2302CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));23032304child_a->set_visible(true);2305pos = { 100, 160 + sep.x };2306MessageQueue::get_singleton()->flush();2307CHECK(split_container->get_split_offsets() == pos);2308CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));23092310// Both visible children are the same size.2311child_a->set_visible(false);2312pos = { (int)split_container->get_size().x / 2 - sep.x / 2 };2313split_container->set_split_offsets(pos);23142315MessageQueue::get_singleton()->flush();2316CHECK(split_container->get_split_offsets() == pos);2317CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));2318CHECK(child_b->get_size().x == child_c->get_size().x);23192320child_a->set_size(Vector2(100, 100));2321MessageQueue::get_singleton()->flush();2322CHECK(split_container->get_split_offsets() == pos);2323CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));23242325child_a->set_visible(true);2326pos = { 100, (int)split_container->get_size().x / 2 + 50 };2327MessageQueue::get_singleton()->flush();2328CHECK(split_container->get_split_offsets() == pos);2329CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));2330CHECK(child_b->get_size().x == child_c->get_size().x);23312332// Second child is slightly larger than the last child.2333child_a->set_visible(false);2334pos = { (int)split_container->get_size().x / 2 - sep.x / 2 + 20 };2335split_container->set_split_offsets(pos);23362337MessageQueue::get_singleton()->flush();2338CHECK(split_container->get_split_offsets() == pos);2339CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));23402341child_a->set_size(Vector2(100, 100));2342MessageQueue::get_singleton()->flush();2343CHECK(split_container->get_split_offsets() == pos);2344CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));23452346child_a->set_visible(true);2347pos = { 100, (int)split_container->get_size().x / 2 + 50 };2348MessageQueue::get_singleton()->flush();2349CHECK(split_container->get_split_offsets() == pos);2350CHECK_RECTS(get_rects_multi(split_container, pos, sep.x), get_child_rects(split_container));2351CHECK(child_b->get_size().x == child_c->get_size().x);2352}23532354memdelete(split_container);2355}23562357} // namespace TestSplitContainer235823592360