Add XCUI layout engine MVP and archive subplan 02
This commit is contained in:
130
tests/Core/Math/test_ui_layout.cpp
Normal file
130
tests/Core/Math/test_ui_layout.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/UI/Layout/LayoutEngine.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::UI::UIRect;
|
||||
using XCEngine::UI::UISize;
|
||||
using XCEngine::UI::Layout::ArrangeOverlayLayout;
|
||||
using XCEngine::UI::Layout::ArrangeStackLayout;
|
||||
using XCEngine::UI::Layout::MeasureOverlayLayout;
|
||||
using XCEngine::UI::Layout::MeasureStackLayout;
|
||||
using XCEngine::UI::Layout::UILayoutAlignment;
|
||||
using XCEngine::UI::Layout::UILayoutAxis;
|
||||
using XCEngine::UI::Layout::UILayoutConstraints;
|
||||
using XCEngine::UI::Layout::UILayoutItem;
|
||||
using XCEngine::UI::Layout::UILayoutLength;
|
||||
using XCEngine::UI::Layout::UILayoutThickness;
|
||||
using XCEngine::UI::Layout::UIOverlayLayoutOptions;
|
||||
using XCEngine::UI::Layout::UIStackLayoutOptions;
|
||||
|
||||
void ExpectRect(
|
||||
const UIRect& rect,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height) {
|
||||
EXPECT_FLOAT_EQ(rect.x, x);
|
||||
EXPECT_FLOAT_EQ(rect.y, y);
|
||||
EXPECT_FLOAT_EQ(rect.width, width);
|
||||
EXPECT_FLOAT_EQ(rect.height, height);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(UI_Layout, MeasureHorizontalStackAccumulatesSpacingPaddingAndCrossExtent) {
|
||||
UIStackLayoutOptions options = {};
|
||||
options.axis = UILayoutAxis::Horizontal;
|
||||
options.spacing = 5.0f;
|
||||
options.padding = UILayoutThickness::Symmetric(10.0f, 6.0f);
|
||||
|
||||
std::vector<UILayoutItem> items(2);
|
||||
items[0].desiredContentSize = UISize(40.0f, 20.0f);
|
||||
items[1].desiredContentSize = UISize(60.0f, 30.0f);
|
||||
|
||||
const auto result = MeasureStackLayout(options, items);
|
||||
|
||||
EXPECT_FLOAT_EQ(result.desiredSize.width, 125.0f);
|
||||
EXPECT_FLOAT_EQ(result.desiredSize.height, 42.0f);
|
||||
}
|
||||
|
||||
TEST(UI_Layout, ArrangeHorizontalStackDistributesRemainingSpaceToStretchChildren) {
|
||||
UIStackLayoutOptions options = {};
|
||||
options.axis = UILayoutAxis::Horizontal;
|
||||
options.spacing = 5.0f;
|
||||
options.padding = UILayoutThickness::Uniform(10.0f);
|
||||
|
||||
std::vector<UILayoutItem> items(3);
|
||||
items[0].width = UILayoutLength::Pixels(100.0f);
|
||||
items[0].desiredContentSize = UISize(10.0f, 20.0f);
|
||||
|
||||
items[1].width = UILayoutLength::Stretch(1.0f);
|
||||
items[1].desiredContentSize = UISize(30.0f, 20.0f);
|
||||
|
||||
items[2].width = UILayoutLength::Pixels(50.0f);
|
||||
items[2].desiredContentSize = UISize(10.0f, 20.0f);
|
||||
|
||||
const auto result = ArrangeStackLayout(options, items, UIRect(0.0f, 0.0f, 300.0f, 80.0f));
|
||||
|
||||
ExpectRect(result.children[0].arrangedRect, 10.0f, 10.0f, 100.0f, 20.0f);
|
||||
ExpectRect(result.children[1].arrangedRect, 115.0f, 10.0f, 120.0f, 20.0f);
|
||||
ExpectRect(result.children[2].arrangedRect, 240.0f, 10.0f, 50.0f, 20.0f);
|
||||
}
|
||||
|
||||
TEST(UI_Layout, ArrangeVerticalStackSupportsCrossAxisStretch) {
|
||||
UIStackLayoutOptions options = {};
|
||||
options.axis = UILayoutAxis::Vertical;
|
||||
options.spacing = 4.0f;
|
||||
options.padding = UILayoutThickness::Symmetric(8.0f, 6.0f);
|
||||
|
||||
std::vector<UILayoutItem> items(2);
|
||||
items[0].desiredContentSize = UISize(40.0f, 10.0f);
|
||||
items[0].horizontalAlignment = UILayoutAlignment::Stretch;
|
||||
items[1].desiredContentSize = UISize(60.0f, 20.0f);
|
||||
|
||||
const auto result = ArrangeStackLayout(options, items, UIRect(0.0f, 0.0f, 200.0f, 100.0f));
|
||||
|
||||
ExpectRect(result.children[0].arrangedRect, 8.0f, 6.0f, 184.0f, 10.0f);
|
||||
ExpectRect(result.children[1].arrangedRect, 8.0f, 20.0f, 60.0f, 20.0f);
|
||||
}
|
||||
|
||||
TEST(UI_Layout, ArrangeOverlaySupportsCenterAndStretch) {
|
||||
UIOverlayLayoutOptions options = {};
|
||||
options.padding = UILayoutThickness::Uniform(10.0f);
|
||||
|
||||
std::vector<UILayoutItem> items(2);
|
||||
items[0].desiredContentSize = UISize(40.0f, 20.0f);
|
||||
items[0].horizontalAlignment = UILayoutAlignment::Center;
|
||||
items[0].verticalAlignment = UILayoutAlignment::Center;
|
||||
|
||||
items[1].desiredContentSize = UISize(10.0f, 10.0f);
|
||||
items[1].width = UILayoutLength::Stretch();
|
||||
items[1].height = UILayoutLength::Stretch();
|
||||
items[1].margin = UILayoutThickness::Uniform(5.0f);
|
||||
|
||||
const auto result = ArrangeOverlayLayout(options, items, UIRect(0.0f, 0.0f, 100.0f, 60.0f));
|
||||
|
||||
ExpectRect(result.children[0].arrangedRect, 30.0f, 20.0f, 40.0f, 20.0f);
|
||||
ExpectRect(result.children[1].arrangedRect, 15.0f, 15.0f, 70.0f, 30.0f);
|
||||
}
|
||||
|
||||
TEST(UI_Layout, MeasureOverlayRespectsItemMinMaxAndAvailableConstraints) {
|
||||
UIOverlayLayoutOptions options = {};
|
||||
|
||||
std::vector<UILayoutItem> items(1);
|
||||
items[0].width = UILayoutLength::Pixels(500.0f);
|
||||
items[0].desiredContentSize = UISize(10.0f, 10.0f);
|
||||
items[0].minSize = UISize(0.0f, 50.0f);
|
||||
items[0].maxSize = UISize(200.0f, 120.0f);
|
||||
|
||||
const auto result = MeasureOverlayLayout(
|
||||
options,
|
||||
items,
|
||||
UILayoutConstraints::Bounded(150.0f, 100.0f));
|
||||
|
||||
EXPECT_FLOAT_EQ(result.children[0].measuredSize.width, 150.0f);
|
||||
EXPECT_FLOAT_EQ(result.children[0].measuredSize.height, 50.0f);
|
||||
EXPECT_FLOAT_EQ(result.desiredSize.width, 150.0f);
|
||||
EXPECT_FLOAT_EQ(result.desiredSize.height, 50.0f);
|
||||
}
|
||||
Reference in New Issue
Block a user