From 1885e14b0dfe7f7026de986aa807fd695d9c3c3f Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Sep 2024 18:48:44 +0200 Subject: [PATCH] Layout with ratio can now also be created with RelativeValue object as alternative to a string containing a percentage --- include/TGUI/AbsoluteOrRelativeValue.hpp | 4 +++ include/TGUI/Layout.hpp | 10 +++++++ src/Layout.cpp | 9 +++++++ tests/Layouts.cpp | 34 ++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/include/TGUI/AbsoluteOrRelativeValue.hpp b/include/TGUI/AbsoluteOrRelativeValue.hpp index 700cb9ac2..6a7ca147d 100644 --- a/include/TGUI/AbsoluteOrRelativeValue.hpp +++ b/include/TGUI/AbsoluteOrRelativeValue.hpp @@ -164,6 +164,10 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// struct TGUI_API RelativeValue : AbsoluteOrRelativeValue { + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Default constructor that sets the given ratio + /// @param ratio Ratio of the value relative to its parent size + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// explicit constexpr RelativeValue(float ratio) { m_constant = false; diff --git a/include/TGUI/Layout.hpp b/include/TGUI/Layout.hpp index ac3343024..0f41afbe3 100644 --- a/include/TGUI/Layout.hpp +++ b/include/TGUI/Layout.hpp @@ -27,6 +27,7 @@ #include #include +#include #if !TGUI_EXPERIMENTAL_USE_STD_MODULE #include @@ -141,6 +142,15 @@ TGUI_MODULE_EXPORT namespace tgui { } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Constructs the layout from a ratio relative to the parent size + /// + /// @param ratio Ratio to the size of the parent widget + /// + /// Layout(RelativeValue(0.3f)) is equivalent to Layout("30%") + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Layout(RelativeValue ratio); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Constructs the layout based on a string which will be parsed to determine the value of the layout /// diff --git a/src/Layout.cpp b/src/Layout.cpp index b35cd8dc8..d58d9b368 100644 --- a/src/Layout.cpp +++ b/src/Layout.cpp @@ -60,6 +60,15 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Layout::Layout(RelativeValue ratio) : + Layout{Layout::Operation::Multiplies, + std::make_unique(ratio.getRatio()), + std::make_unique(U"&.innersize")} + { + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Layout::Layout(String expression) { // Empty strings have value 0 (although this might indicate a mistake in the expression, it is valid for unary minus, diff --git a/tests/Layouts.cpp b/tests/Layouts.cpp index f759c7162..a93ed70c3 100644 --- a/tests/Layouts.cpp +++ b/tests/Layouts.cpp @@ -85,6 +85,40 @@ TEST_CASE("[Layouts]") SECTION("without strings") { + SECTION("relative values") + { + Layout layout{tgui::RelativeValue(1)}; + REQUIRE(layout.toString() == "100%"); + + Layout layout2{tgui::RelativeValue(0.5f)}; + REQUIRE(layout2.toString() == "50%"); + + REQUIRE(!layout.isConstant()); + + auto button = std::make_shared(); + button->setPosition({tgui::RelativeValue(0.4f), tgui::RelativeValue(0.3f)}); + button->setSize({tgui::RelativeValue(0.2f), tgui::RelativeValue(0.1f)}); + + REQUIRE(button->getSize() == tgui::Vector2f(0, 0)); + REQUIRE(button->getPosition() == tgui::Vector2f(0, 0)); + + auto panel = std::make_shared(); + panel->setSize(400, 300); + panel->add(button); + + REQUIRE(button->getSize() == tgui::Vector2f(80, 30)); + REQUIRE(button->getPosition() == tgui::Vector2f(160, 90)); + + SECTION("Inner size is used") + { + panel->getRenderer()->setBorders({5, 10, 15, 20}); + panel->getRenderer()->setPadding({25, 30, 35, 40}); + + REQUIRE(button->getSize() == tgui::Vector2f(0.2f * (400 - 5 - 15 - 25 - 35), 0.1f * (300 - 10 - 20 - 30 - 40))); + REQUIRE(button->getPosition() == tgui::Vector2f(0.4f * (400 - 5 - 15 - 25 - 35), 0.3f * (300 - 10 - 20 - 30 - 40))); + } + } + SECTION("operators") { Layout l1{2};