From 6e7270aa4fb227f40730358e450417636b962f52 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 9 Oct 2024 22:48:07 +0200 Subject: [PATCH 01/87] Assert that a raylib window has to exist before creating the Gui with the RAYLIB backend --- src/Backend/raylib.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Backend/raylib.cpp b/src/Backend/raylib.cpp index 19a5ee1a7..6376a2669 100644 --- a/src/Backend/raylib.cpp +++ b/src/Backend/raylib.cpp @@ -41,6 +41,8 @@ namespace tgui setBackend(backend); } + TGUI_ASSERT(IsWindowReady(), "Gui can't be created when no raylib window exists yet"); + m_backendRenderTarget = std::make_shared(); getBackend()->attachGui(this); From 842ef890643a63c178a9071f99e55d56e26ff890 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 10 Oct 2024 18:41:17 +0200 Subject: [PATCH 02/87] Let Findglfw3.cmake detect whether the GLFW library is static, to provide a fatal error when building a TGUI dll in such case instead of silently continuing and creating a broken dll file (closes #247) --- cmake/Modules/Findglfw3.cmake | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cmake/Modules/Findglfw3.cmake b/cmake/Modules/Findglfw3.cmake index 7b09f3126..2bcf545bf 100644 --- a/cmake/Modules/Findglfw3.cmake +++ b/cmake/Modules/Findglfw3.cmake @@ -68,15 +68,23 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(glfw3 if(glfw3_FOUND) if(GLFW_LIBRARY AND NOT TARGET glfw) - add_library(glfw UNKNOWN IMPORTED) - set_target_properties(glfw PROPERTIES - IMPORTED_LOCATION "${GLFW_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${GLFW_INCLUDE_DIR}") - get_filename_component(GLFW_LIBRARY_FILENAME "${GLFW_LIBRARY}" NAME) if(GLFW_LIBRARY_FILENAME STREQUAL "glfw3dll.lib" OR GLFW_LIBRARY_FILENAME STREQUAL "libglfw3dll.a") + add_library(glfw UNKNOWN IMPORTED) # UNKNOWN instead of SHARED because we otherwise must also provide the path to the DLL on Windows set_target_properties(glfw PROPERTIES INTERFACE_COMPILE_DEFINITIONS "GLFW_DLL") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows" + AND (GLFW_LIBRARY_FILENAME STREQUAL "libglfw3.a" + OR GLFW_LIBRARY_FILENAME STREQUAL "glfw3.lib" + OR GLFW_LIBRARY_FILENAME STREQUAL "glfw3_mt.lib")) + # If we know that the library is static then explicitly mark it as such so that we can give an error when building TGUI as a dll + add_library(glfw STATIC IMPORTED) + else() + add_library(glfw UNKNOWN IMPORTED) endif() + + set_target_properties(glfw PROPERTIES + IMPORTED_LOCATION "${GLFW_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GLFW_INCLUDE_DIR}") endif() endif() From d60c5bb90ee5ec40f170a9eb4e1891993124cc77 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 6 Nov 2024 19:11:21 +0100 Subject: [PATCH 03/87] Ignore SDL events that were generated on another window --- include/TGUI/Backend/Window/Backend.hpp | 2 +- include/TGUI/Layout.hpp | 2 +- include/TGUI/TextStyle.hpp | 4 +- include/TGUI/Widgets/ClickableWidget.hpp | 2 + src/Backend/Window/Backend.cpp | 8 ++++ src/Backend/Window/SDL/BackendGuiSDL.cpp | 51 ++++++++++++++++++++++++ tests/BackendEvents.cpp | 22 ++++++++++ 7 files changed, 87 insertions(+), 4 deletions(-) diff --git a/include/TGUI/Backend/Window/Backend.hpp b/include/TGUI/Backend/Window/Backend.hpp index f35e638dd..baea3d233 100644 --- a/include/TGUI/Backend/Window/Backend.hpp +++ b/include/TGUI/Backend/Window/Backend.hpp @@ -226,7 +226,7 @@ TGUI_MODULE_EXPORT namespace tgui /// /// @return Whether queries modifier key is being pressed ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_DEPRECATED("Use gui.isKeyboardModifierPressed(modifierKey) instead") TGUI_NODISCARD virtual bool isKeyboardModifierPressed(Event::KeyModifier modifierKey) = 0; + TGUI_DEPRECATED("Use gui.isKeyboardModifierPressed(modifierKey) instead") TGUI_NODISCARD virtual bool isKeyboardModifierPressed(Event::KeyModifier modifierKey); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Changes the contents of the clipboard diff --git a/include/TGUI/Layout.hpp b/include/TGUI/Layout.hpp index 0f41afbe3..7a8ee99a8 100644 --- a/include/TGUI/Layout.hpp +++ b/include/TGUI/Layout.hpp @@ -89,7 +89,7 @@ TGUI_MODULE_EXPORT namespace tgui Right, //!< Places the widget on the right side and sets its height to the area between Top and Bottom aligned components. Width needs to be manually set. Bottom, //!< Places the widget on on the bottom and sets its width to the area between Leftmost and Rightmost aligned components. Height needs to be manually set. Leftmost, //!< Places the widget on the left side and sets height to 100%. Width needs to be manually set. Same as Left alignment if no widget uses Top or Bottom alignment. - Rightmost, //!< Places the widget on the right side and sets height to 100%. Width needs to be manually set. Same as Left alignment if no widget uses Top or Bottom alignment. + Rightmost, //!< Places the widget on the right side and sets height to 100%. Width needs to be manually set. Same as Right alignment if no widget uses Top or Bottom alignment. Fill //!< Sets the position and size to fill the entire area that isn't already taken by components with the other AutoLayout values. }; diff --git a/include/TGUI/TextStyle.hpp b/include/TGUI/TextStyle.hpp index 4e865c05a..766cb4609 100644 --- a/include/TGUI/TextStyle.hpp +++ b/include/TGUI/TextStyle.hpp @@ -31,9 +31,9 @@ TGUI_MODULE_EXPORT namespace tgui { - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Enumeration of the text drawing styles - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// enum TextStyle : unsigned int { Regular = 0, //!< Regular characters, no style diff --git a/include/TGUI/Widgets/ClickableWidget.hpp b/include/TGUI/Widgets/ClickableWidget.hpp index 21f50f1ec..58036bde9 100644 --- a/include/TGUI/Widgets/ClickableWidget.hpp +++ b/include/TGUI/Widgets/ClickableWidget.hpp @@ -33,6 +33,8 @@ TGUI_MODULE_EXPORT namespace tgui { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Clickable widget + /// + /// The widget acts as an invisible clickable area. It is also used as a base class for other widgets that are clickable. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class TGUI_API ClickableWidget : public Widget { diff --git a/src/Backend/Window/Backend.cpp b/src/Backend/Window/Backend.cpp index 5963437e2..2a58cbcc4 100644 --- a/src/Backend/Window/Backend.cpp +++ b/src/Backend/Window/Backend.cpp @@ -159,6 +159,14 @@ namespace tgui #endif ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Backend::isKeyboardModifierPressed(Event::KeyModifier) + { + // All backends must either override this function or the one inside the gui class. + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Backend::setClipboard(const String& contents) { m_clipboardContents = contents; diff --git a/src/Backend/Window/SDL/BackendGuiSDL.cpp b/src/Backend/Window/SDL/BackendGuiSDL.cpp index a9ec3ddf7..2326dca0e 100644 --- a/src/Backend/Window/SDL/BackendGuiSDL.cpp +++ b/src/Backend/Window/SDL/BackendGuiSDL.cpp @@ -185,6 +185,43 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if SDL_MAJOR_VERSION < 3 + static std::uint32_t getWindowIdFromEvent(const SDL_Event& eventSDL) + { + switch (eventSDL.type) + { + case SDL_WINDOWEVENT: + return eventSDL.window.windowID; + + case SDL_EVENT_TEXT_INPUT: + return eventSDL.text.windowID; + + case SDL_EVENT_KEY_DOWN: + return eventSDL.key.windowID; + + case SDL_EVENT_MOUSE_WHEEL: + return eventSDL.wheel.windowID; + + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + return eventSDL.button.windowID; + + case SDL_EVENT_MOUSE_MOTION: + return eventSDL.motion.windowID; + + case SDL_EVENT_FINGER_DOWN: + case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_MOTION: + return eventSDL.tfinger.windowID; + + default: + return 0; + } + } +#endif + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool BackendGuiSDL::convertEvent(const SDL_Event& eventSDL, Event& eventTGUI) { switch (eventSDL.type) @@ -460,6 +497,20 @@ namespace tgui bool BackendGuiSDL::handleEvent(const SDL_Event& sdlEvent) { + // Ignore events from a window other than the one used by the gui. + // Not all events are related to a window, and manually crafted events will also not have a valid window id, + // so if the event has no associated window then we will also process it. +#if SDL_MAJOR_VERSION >= 3 + SDL_Window* window = SDL_GetWindowFromEvent(&sdlEvent); + if (window && (window != m_window)) + return false; +#else + const std::uint32_t eventWindowId = getWindowIdFromEvent(sdlEvent); + const std::uint32_t windowId = SDL_GetWindowID(m_window); + if ((eventWindowId != 0) && (windowId != 0) && (eventWindowId != windowId)) + return false; +#endif + // Detect scrolling with two fingers by examining touch events if ((sdlEvent.type == SDL_EVENT_FINGER_DOWN) || (sdlEvent.type == SDL_EVENT_FINGER_UP) || (sdlEvent.type == SDL_EVENT_FINGER_MOTION)) { diff --git a/tests/BackendEvents.cpp b/tests/BackendEvents.cpp index 31abcd3ea..41507f7a6 100644 --- a/tests/BackendEvents.cpp +++ b/tests/BackendEvents.cpp @@ -1205,6 +1205,7 @@ TEST_CASE("[Backend events]") eventSDL.type = SDL_WINDOWEVENT; eventSDL.window.event = SDL_WINDOWEVENT_FOCUS_GAINED; #endif + eventSDL.window.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1220,6 +1221,7 @@ TEST_CASE("[Backend events]") eventSDL.type = SDL_WINDOWEVENT; eventSDL.window.event = SDL_WINDOWEVENT_FOCUS_LOST; #endif + eventSDL.window.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1247,6 +1249,7 @@ TEST_CASE("[Backend events]") #endif eventSDL.window.data1 = 400; eventSDL.window.data2 = 300; + eventSDL.window.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1259,6 +1262,7 @@ TEST_CASE("[Backend events]") { SDL_Event eventSDL; eventSDL.type = SDL_EVENT_TEXT_INPUT; + eventSDL.text.windowID = 0; #if SDL_MAJOR_VERSION >= 3 char textInput[4] = { static_cast(static_cast(0xE2)), @@ -1295,10 +1299,12 @@ TEST_CASE("[Backend events]") eventSDL.motion.which = 1; eventSDL.motion.x = 200; eventSDL.motion.y = 150; + eventSDL.motion.windowID = 0; backendGuiSDL->handleEvent(eventSDL); #endif eventSDL.type = SDL_EVENT_MOUSE_WHEEL; + eventSDL.wheel.windowID = 0; eventSDL.wheel.x = 0; eventSDL.wheel.y = 2; eventSDL.wheel.direction = SDL_MOUSEWHEEL_NORMAL; @@ -1337,6 +1343,7 @@ TEST_CASE("[Backend events]") eventSDL.button.button = SDL_BUTTON_LEFT; eventSDL.button.x = 200; eventSDL.button.y = 150; + eventSDL.button.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1366,6 +1373,7 @@ TEST_CASE("[Backend events]") eventSDL.button.button = SDL_BUTTON_LEFT; eventSDL.button.x = 200; eventSDL.button.y = 150; + eventSDL.button.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1394,6 +1402,7 @@ TEST_CASE("[Backend events]") eventSDL.motion.which = 1; eventSDL.motion.x = 200; eventSDL.motion.y = 150; + eventSDL.motion.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1420,6 +1429,7 @@ TEST_CASE("[Backend events]") #endif eventSDL.tfinger.x = 200.f / windowSize.x; eventSDL.tfinger.y = 150.f / windowSize.y; + eventSDL.tfinger.windowID = 0; tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1453,6 +1463,8 @@ TEST_CASE("[Backend events]") eventSDL.type = SDL_WINDOWEVENT; eventSDL.window.event = SDL_WINDOWEVENT_ENTER; #endif + eventSDL.window.windowID = 0; + tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); REQUIRE(eventTGUI.type == tgui::Event::Type::MouseEntered); @@ -1467,6 +1479,8 @@ TEST_CASE("[Backend events]") eventSDL.type = SDL_WINDOWEVENT; eventSDL.window.event = SDL_WINDOWEVENT_LEAVE; #endif + eventSDL.window.windowID = 0; + tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); REQUIRE(eventTGUI.type == tgui::Event::Type::MouseLeft); @@ -1500,6 +1514,7 @@ TEST_CASE("[Backend events]") // Type 3 characters in the edit box SDL_Event eventSDL; eventSDL.type = SDL_EVENT_TEXT_INPUT; + eventSDL.text.windowID = 0; #if SDL_MAJOR_VERSION >= 3 char textInput[2] = "A"; eventSDL.text.text = textInput; @@ -1554,10 +1569,12 @@ TEST_CASE("[Backend events]") eventSDL.motion.which = 1; eventSDL.motion.x = 260; eventSDL.motion.y = 80; + eventSDL.motion.windowID = 0; backendGuiSDL->handleEvent(eventSDL); #endif eventSDL.type = SDL_EVENT_MOUSE_WHEEL; eventSDL.wheel.direction = SDL_MOUSEWHEEL_NORMAL; + eventSDL.wheel.windowID = 0; eventSDL.wheel.x = 0; eventSDL.wheel.y = 4; #if (SDL_MAJOR_VERSION == 2) && ((SDL_MINOR_VERSION > 0) || (SDL_PATCHLEVEL >= 18)) @@ -1580,6 +1597,7 @@ TEST_CASE("[Backend events]") eventSDL.motion.which = 1; eventSDL.motion.x = 260; eventSDL.motion.y = 80; + eventSDL.motion.windowID = 0; backendGuiSDL->handleEvent(eventSDL); slider->onMouseLeave([&]{ genericCallback(mouseLeftCount); }); #if SDL_MAJOR_VERSION >= 3 @@ -1598,23 +1616,27 @@ TEST_CASE("[Backend events]") eventSDL.button.button = SDL_BUTTON_LEFT; eventSDL.button.x = 320; eventSDL.button.y = 100; + eventSDL.button.windowID = 0; backendGuiSDL->handleEvent(eventSDL); eventSDL.type = SDL_EVENT_MOUSE_MOTION; eventSDL.motion.which = 1; eventSDL.motion.x = 300; eventSDL.motion.y = 105; + eventSDL.motion.windowID = 0; backendGuiSDL->handleEvent(eventSDL); eventSDL.type = SDL_EVENT_MOUSE_BUTTON_UP; eventSDL.button.which = 1; eventSDL.button.button = SDL_BUTTON_LEFT; eventSDL.button.x = 290; eventSDL.button.y = 110; + eventSDL.button.windowID = 0; backendGuiSDL->handleEvent(eventSDL); // Resize the child window using touch events (decrease height with 10px) // Note that the resizing ignores the position of the touch ended event const tgui::Vector2f windowSize = backendGuiSDL->getViewport().getSize(); eventSDL.type = SDL_EVENT_FINGER_DOWN; + eventSDL.tfinger.windowID = 0; #if SDL_MAJOR_VERSION >= 3 eventSDL.tfinger.touchID = 1; #else From dfa38151c11e0d19d019f24cf8feac0d6e9c8041 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 6 Nov 2024 19:29:21 +0100 Subject: [PATCH 04/87] Last commit didn't compile with SDL < 2.0.12 --- src/Backend/Window/SDL/BackendGuiSDL.cpp | 3 ++- tests/BackendEvents.cpp | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Backend/Window/SDL/BackendGuiSDL.cpp b/src/Backend/Window/SDL/BackendGuiSDL.cpp index 2326dca0e..77351cc14 100644 --- a/src/Backend/Window/SDL/BackendGuiSDL.cpp +++ b/src/Backend/Window/SDL/BackendGuiSDL.cpp @@ -209,11 +209,12 @@ namespace tgui case SDL_EVENT_MOUSE_MOTION: return eventSDL.motion.windowID; + #if ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION > 0)) || ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION == 0) && (SDL_PATCHLEVEL >= 12)) case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_MOTION: return eventSDL.tfinger.windowID; - + #endif default: return 0; } diff --git a/tests/BackendEvents.cpp b/tests/BackendEvents.cpp index 41507f7a6..5c2e9795a 100644 --- a/tests/BackendEvents.cpp +++ b/tests/BackendEvents.cpp @@ -1429,7 +1429,9 @@ TEST_CASE("[Backend events]") #endif eventSDL.tfinger.x = 200.f / windowSize.x; eventSDL.tfinger.y = 150.f / windowSize.y; +#if (SDL_MAJOR_VERSION > 2) || ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION > 0)) || ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION == 0) && (SDL_PATCHLEVEL >= 12)) eventSDL.tfinger.windowID = 0; +#endif tgui::Event eventTGUI; REQUIRE(backendGuiSDL->convertEvent(eventSDL, eventTGUI)); @@ -1636,7 +1638,9 @@ TEST_CASE("[Backend events]") // Note that the resizing ignores the position of the touch ended event const tgui::Vector2f windowSize = backendGuiSDL->getViewport().getSize(); eventSDL.type = SDL_EVENT_FINGER_DOWN; +#if (SDL_MAJOR_VERSION > 2) || ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION > 0)) || ((SDL_MAJOR_VERSION == 2) && (SDL_MINOR_VERSION == 0) && (SDL_PATCHLEVEL >= 12)) eventSDL.tfinger.windowID = 0; +#endif #if SDL_MAJOR_VERSION >= 3 eventSDL.tfinger.touchID = 1; #else From 2c0f1aa02d2bd4e27bb227a15f91d14a37ae826e Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 6 Nov 2024 19:47:18 +0100 Subject: [PATCH 05/87] Update iOS SFML build on CI from deprecated macOS 12 to macOS 15 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a377876f8..ab27f9fab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -993,7 +993,7 @@ jobs: #---------------------------------------- ios-sfml-graphics: - runs-on: macos-12 + runs-on: macos-15 env: SFML_VERSION: 2.6.x # At least 2.6.2 is required steps: From 01d829766872f71f4d23eb6bcd3c1f2e2b4991d3 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Tue, 12 Nov 2024 09:14:25 +0100 Subject: [PATCH 06/87] Link nightly builds to SFML 2.6.2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab27f9fab..1b178a211 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1127,7 +1127,7 @@ jobs: needs: [linux, linux-latest-dev, linux-oldest, linux-per-backend, windows, windows-oldest, windows-clang, windows-static-mt, macos, android-sdl, android-sfml-graphics, ios-sfml-graphics, ios-sdl] runs-on: windows-2019 env: - SFML_VERSION: 2.6.1 + SFML_VERSION: 2.6.2 MSVC_TOOLSET_VERSION: 141 # VS2017 steps: - name: Checkout TGUI From ad1827361cd5ee14cd43b94c64e0cb190d61b62f Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 20 Nov 2024 19:46:20 +0100 Subject: [PATCH 07/87] Print a warning in debug mode when 2 widgets added to the same parent have the same name --- src/Container.cpp | 19 +++++++++++++++++++ src/Widget.cpp | 26 +++++++++++++++++++++----- tests/Container.cpp | 14 ++++++++++++++ tests/Widget.cpp | 2 ++ tests/Widgets/PanelListBox.cpp | 2 +- 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/Container.cpp b/src/Container.cpp index a01e709b4..5ca63e91f 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -307,9 +307,28 @@ namespace tgui TGUI_ASSERT(widgetPtr != nullptr, "Can't add nullptr to container"); m_widgets.push_back(widgetPtr); + if (!widgetName.empty()) widgetPtr->setWidgetName(widgetName); +#if !defined(NDEBUG) && !defined(TGUI_NO_RUNTIME_WARNINGS) + // TGUI_NEXT: Disallow multiple widgets with the same name (if name isn't empty). Throw exception if duplicate found. + // If the name passed to this function is empty then it's still possible that the widget already had a name, + // otherwise usedWidgetName will be the same value as widgetName. + const String& usedWidgetName = widgetPtr->getWidgetName(); + if (!usedWidgetName.empty() && !usedWidgetName.starts_with("#TGUI_INTERNAL$")) + { + for (const auto& existingWidget : m_widgets) + { + if ((existingWidget != widgetPtr) && (existingWidget->getWidgetName() == usedWidgetName)) + { + TGUI_PRINT_WARNING("Multiple widgets with name '" + usedWidgetName + "' were added to the same parent."); + break; + } + } + } +#endif + widgetAdded(widgetPtr); if (widgetPtr->getAutoLayout() != AutoLayout::Manual) diff --git a/src/Widget.cpp b/src/Widget.cpp index d6895a8b0..0bb87a000 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -1164,15 +1164,31 @@ namespace tgui void Widget::setWidgetName(const String& name) { - if (m_name != name) + if (m_name == name) + return; + + m_name = name; + + if (!m_parent) + return; + + SignalManager::getSignalManager()->remove(this); + SignalManager::getSignalManager()->add(shared_from_this()); + +#if !defined(NDEBUG) && !defined(TGUI_NO_RUNTIME_WARNINGS) + // TGUI_NEXT: Disallow multiple widgets with the same name (if name isn't empty). Throw exception if duplicate found. + if (!name.empty() && !name.starts_with("#TGUI_INTERNAL$")) { - m_name = name; - if (m_parent) + for (const auto& widget : m_parent->getWidgets()) { - SignalManager::getSignalManager()->remove(this); - SignalManager::getSignalManager()->add(shared_from_this()); + if ((widget.get() != this) && (widget->getWidgetName() == name)) + { + TGUI_PRINT_WARNING("Multiple widgets with name '" + name + "' were added to the same parent."); + break; + } } } +#endif } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/Container.cpp b/tests/Container.cpp index 97f72439a..7478a11f0 100644 --- a/tests/Container.cpp +++ b/tests/Container.cpp @@ -122,6 +122,9 @@ TEST_CASE("[Container]") SECTION("reusing name") { + // Ignore warnings about duplicate names being used + std::streambuf *oldbuf = std::cerr.rdbuf(nullptr); + container->removeAllWidgets(); auto child1 = tgui::Panel::create(); @@ -160,6 +163,17 @@ TEST_CASE("[Container]") // Removing the found indirect child means that there is no more widget with that name child1->remove(child4); REQUIRE(container->get("name") == nullptr); + + // Changing the name of a widget affects which one is found + container->add(child2, "other"); + container->add(child3, "name"); + REQUIRE(container->get("name") == child3); + REQUIRE(container->get("other") == child2); + child2->setWidgetName("name"); + REQUIRE(container->get("name") == child2); + REQUIRE(container->get("other") == nullptr); + + std::cerr.rdbuf(oldbuf); } } diff --git a/tests/Widget.cpp b/tests/Widget.cpp index 8a8b86493..c0a418d28 100644 --- a/tests/Widget.cpp +++ b/tests/Widget.cpp @@ -576,7 +576,9 @@ TEST_CASE("[Widget]") REQUIRE(parent->getWidgets().size() == 1); parent->loadWidgetsFromFile("WidgetFileClickableWidget1.txt"); REQUIRE(parent->getWidgets().size() == 1); + std::streambuf *oldbuf = std::cerr.rdbuf(nullptr); // Ignore warning about duplicate name being used parent->loadWidgetsFromFile("WidgetFileClickableWidget1.txt", false); + std::cerr.rdbuf(oldbuf); REQUIRE(parent->getWidgets().size() == 2); } diff --git a/tests/Widgets/PanelListBox.cpp b/tests/Widgets/PanelListBox.cpp index 781acb6ab..d287249d4 100644 --- a/tests/Widgets/PanelListBox.cpp +++ b/tests/Widgets/PanelListBox.cpp @@ -138,8 +138,8 @@ TEST_CASE("[PanelListBox]") REQUIRE(panelListBox->getItemByIndex(0) == item3); const auto item5 = panelListBox->addItem("5"); - const auto item5_second = panelListBox->addItem("5"); const auto item6 = panelListBox->addItem("6"); + const auto item7 = panelListBox->addItem("7"); REQUIRE(panelListBox->getItemCount() == 4); panelListBox->removeAllItems(); REQUIRE(panelListBox->getItemCount() == 0); From 7bac67870af551daf792db6b7ba6cf9a9ece456b Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 20 Nov 2024 20:09:06 +0100 Subject: [PATCH 08/87] Added missing include in tests --- tests/Container.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Container.cpp b/tests/Container.cpp index 7478a11f0..70d567d49 100644 --- a/tests/Container.cpp +++ b/tests/Container.cpp @@ -22,6 +22,8 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include + #include "Tests.hpp" TEST_CASE("[Container]") From 4aab4c30666e5c02f6bb7e11241a1e2c3412fa7e Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 20 Nov 2024 20:09:32 +0100 Subject: [PATCH 09/87] Ignore -Wmaybe-uninitialized warning in nanosvg --- include/TGUI/extlibs/IncludeNanoSVG.hpp | 3 +++ include/TGUI/extlibs/nanosvg/nanosvgrast.h | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/TGUI/extlibs/IncludeNanoSVG.hpp b/include/TGUI/extlibs/IncludeNanoSVG.hpp index 757b1140a..6c3c55071 100644 --- a/include/TGUI/extlibs/IncludeNanoSVG.hpp +++ b/include/TGUI/extlibs/IncludeNanoSVG.hpp @@ -34,6 +34,9 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wcast-align" # pragma GCC diagnostic ignored "-Wshadow" +# if !defined(__clang__) +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +# endif #elif defined (_MSC_VER) # if defined(__clang__) # pragma clang diagnostic push diff --git a/include/TGUI/extlibs/nanosvg/nanosvgrast.h b/include/TGUI/extlibs/nanosvg/nanosvgrast.h index a83db2726..a4b866beb 100644 --- a/include/TGUI/extlibs/nanosvg/nanosvgrast.h +++ b/include/TGUI/extlibs/nanosvg/nanosvgrast.h @@ -346,6 +346,7 @@ static float nsvg__normalize(float *x, float* y) } static float nsvg__absf(float x) { return x < 0 ? -x : x; } +static float nsvg__roundf(float x) { return (x >= 0) ? floorf(x + 0.5) : ceilf(x - 0.5); } static void nsvg__flattenCubicBez(NSVGrasterizer* r, float x1, float y1, float x2, float y2, @@ -888,10 +889,10 @@ static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float sta // STBTT_assert(e->y0 <= start_point); // round dx down to avoid going too far if (dxdy < 0) - z->dx = (int)(-floorf(NSVG__FIX * -dxdy)); + z->dx = (int)(-nsvg__roundf(NSVG__FIX * -dxdy)); else - z->dx = (int)floorf(NSVG__FIX * dxdy); - z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); + z->dx = (int)nsvg__roundf(NSVG__FIX * dxdy); + z->x = (int)nsvg__roundf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); // z->x -= off_x * FIX; z->ey = e->y1; z->next = 0; @@ -1298,7 +1299,7 @@ static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opac if (grad->nstops == 0) { for (i = 0; i < 256; i++) cache->colors[i] = 0; - } if (grad->nstops == 1) { + } else if (grad->nstops == 1) { for (i = 0; i < 256; i++) cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity); } else { From c26dd6e765263bd4aa6319ab848a865e8c907ea5 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Tue, 26 Nov 2024 14:26:14 +0100 Subject: [PATCH 10/87] Update stb_image version --- include/TGUI/extlibs/stb/stb_image.h | 355 ++++++++++++++------------- 1 file changed, 178 insertions(+), 177 deletions(-) diff --git a/include/TGUI/extlibs/stb/stb_image.h b/include/TGUI/extlibs/stb/stb_image.h index 5e807a0a6..9eedabedc 100755 --- a/include/TGUI/extlibs/stb/stb_image.h +++ b/include/TGUI/extlibs/stb/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb +/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb no warranty implied; use at your own risk Do this: @@ -48,6 +48,8 @@ LICENSE RECENT REVISION HISTORY: + 2.30 (2024-05-31) avoid erroneous gcc warning + 2.29 (2023-05-xx) optimizations 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes 2.26 (2020-07-13) many minor fixes @@ -1072,8 +1074,8 @@ static int stbi__addints_valid(int a, int b) return a <= INT_MAX - b; } -// returns 1 if the product of two signed shorts is valid, 0 on overflow. -static int stbi__mul2shorts_valid(short a, short b) +// returns 1 if the product of two ints fits in a signed short, 0 on overflow. +static int stbi__mul2shorts_valid(int a, int b) { if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid @@ -3384,13 +3386,13 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) return 1; } -static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) +static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) { // some JPEGs have junk at end, skip over it but if we find what looks // like a valid marker, resume there while (!stbi__at_eof(j->s)) { - int x = stbi__get8(j->s); - while (x == 255) { // might be a marker + stbi_uc x = stbi__get8(j->s); + while (x == 0xff) { // might be a marker if (stbi__at_eof(j->s)) return STBI__MARKER_none; x = stbi__get8(j->s); if (x != 0x00 && x != 0xff) { @@ -4176,6 +4178,7 @@ typedef struct { stbi_uc *zbuffer, *zbuffer_end; int num_bits; + int hit_zeof_once; stbi__uint32 code_buffer; char *zout; @@ -4242,9 +4245,20 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) int b,s; if (a->num_bits < 16) { if (stbi__zeof(a)) { - return -1; /* report error for unexpected end of data. */ + if (!a->hit_zeof_once) { + // This is the first time we hit eof, insert 16 extra padding btis + // to allow us to keep going; if we actually consume any of them + // though, that is invalid data. This is caught later. + a->hit_zeof_once = 1; + a->num_bits += 16; // add 16 implicit zero bits + } else { + // We already inserted our extra 16 padding bits and are again + // out, this stream is actually prematurely terminated. + return -1; + } + } else { + stbi__fill_bits(a); } - stbi__fill_bits(a); } b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; if (b) { @@ -4309,6 +4323,13 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) int len,dist; if (z == 256) { a->zout = zout; + if (a->hit_zeof_once && a->num_bits < 16) { + // The first time we hit zeof, we inserted 16 extra zero bits into our bit + // buffer so the decoder can just do its speculative decoding. But if we + // actually consumed any of those bits (which is the case when num_bits < 16), + // the stream actually read past the end so it is malformed. + return stbi__err("unexpected end","Corrupt PNG"); + } return 1; } if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data @@ -4320,7 +4341,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) dist = stbi__zdist_base[z]; if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (zout + len > a->zout_end) { + if (len > a->zout_end - zout) { if (!stbi__zexpand(a, zout, len)) return 0; zout = a->zout; } @@ -4464,6 +4485,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) if (!stbi__parse_zlib_header(a)) return 0; a->num_bits = 0; a->code_buffer = 0; + a->hit_zeof_once = 0; do { final = stbi__zreceive(a,1); type = stbi__zreceive(a,2); @@ -4619,9 +4641,8 @@ enum { STBI__F_up=2, STBI__F_avg=3, STBI__F_paeth=4, - // synthetic filters used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first, - STBI__F_paeth_first + // synthetic filter used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first }; static stbi_uc first_row_filter[5] = @@ -4630,29 +4651,56 @@ static stbi_uc first_row_filter[5] = STBI__F_sub, STBI__F_none, STBI__F_avg_first, - STBI__F_paeth_first + STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub }; static int stbi__paeth(int a, int b, int c) { - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; + // This formulation looks very different from the reference in the PNG spec, but is + // actually equivalent and has favorable data dependencies and admits straightforward + // generation of branch-free code, which helps performance significantly. + int thresh = c*3 - (a + b); + int lo = a < b ? a : b; + int hi = a < b ? b : a; + int t0 = (hi <= thresh) ? lo : c; + int t1 = (thresh <= lo) ? hi : t0; + return t1; } static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; +// adds an extra all-255 alpha channel +// dest == src is legal +// img_n must be 1 or 3 +static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n) +{ + int i; + // must process data backwards since we allow dest==src + if (img_n == 1) { + for (i=x-1; i >= 0; --i) { + dest[i*2+1] = 255; + dest[i*2+0] = src[i]; + } + } else { + STBI_ASSERT(img_n == 3); + for (i=x-1; i >= 0; --i) { + dest[i*4+3] = 255; + dest[i*4+2] = src[i*3+2]; + dest[i*4+1] = src[i*3+1]; + dest[i*4+0] = src[i*3+0]; + } + } +} + // create the png data from post-deflated data static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) { - int bytes = (depth == 16? 2 : 1); + int bytes = (depth == 16 ? 2 : 1); stbi__context *s = a->s; stbi__uint32 i,j,stride = x*out_n*bytes; stbi__uint32 img_len, img_width_bytes; + stbi_uc *filter_buf; + int all_ok = 1; int k; int img_n = s->img_n; // copy it into a local for later @@ -4664,8 +4712,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); + // note: error exits here don't need to clean up a->out individually, + // stbi__do_png always does on error. if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); + if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); img_len = (img_width_bytes + 1) * y; // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, @@ -4673,189 +4724,137 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r // so just check for raw_len < img_len always. if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + // Allocate two scan lines worth of filter workspace buffer. + filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); + if (!filter_buf) return stbi__err("outofmem", "Out of memory"); + + // Filtering for low-bit-depth images + if (depth < 8) { + filter_bytes = 1; + width = img_width_bytes; + } + for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *prior; + // cur/prior filter buffers alternate + stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; + stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; + stbi_uc *dest = a->out + stride*j; + int nk = width * filter_bytes; int filter = *raw++; - if (filter > 4) - return stbi__err("invalid filter","Corrupt PNG"); - - if (depth < 8) { - if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG"); - cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; + // check filter type + if (filter > 4) { + all_ok = stbi__err("invalid filter","Corrupt PNG"); + break; } - prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above // if first row, use special filter that doesn't sample previous row if (j == 0) filter = first_row_filter[filter]; - // handle first byte explicitly - for (k=0; k < filter_bytes; ++k) { - switch (filter) { - case STBI__F_none : cur[k] = raw[k]; break; - case STBI__F_sub : cur[k] = raw[k]; break; - case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; - case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; - case STBI__F_avg_first : cur[k] = raw[k]; break; - case STBI__F_paeth_first: cur[k] = raw[k]; break; - } - } - - if (depth == 8) { - if (img_n != out_n) - cur[img_n] = 255; // first pixel - raw += img_n; - cur += out_n; - prior += out_n; - } else if (depth == 16) { - if (img_n != out_n) { - cur[filter_bytes] = 255; // first pixel top byte - cur[filter_bytes+1] = 255; // first pixel bottom byte - } - raw += filter_bytes; - cur += output_bytes; - prior += output_bytes; - } else { - raw += 1; - cur += 1; - prior += 1; + // perform actual filtering + switch (filter) { + case STBI__F_none: + memcpy(cur, raw, nk); + break; + case STBI__F_sub: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); + break; + case STBI__F_up: + for (k = 0; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); + break; + case STBI__F_avg: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); + break; + case STBI__F_paeth: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); + break; + case STBI__F_avg_first: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); + break; } - // this is a little gross, so that we don't switch per-pixel or per-component - if (depth < 8 || img_n == out_n) { - int nk = (width - 1)*filter_bytes; - #define STBI__CASE(f) \ - case f: \ - for (k=0; k < nk; ++k) - switch (filter) { - // "none" filter turns into a memcpy here; make that explicit. - case STBI__F_none: memcpy(cur, raw, nk); break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; - } - #undef STBI__CASE - raw += nk; - } else { - STBI_ASSERT(img_n+1 == out_n); - #define STBI__CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ - for (k=0; k < filter_bytes; ++k) - switch (filter) { - STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; - } - #undef STBI__CASE - - // the loop above sets the high byte of the pixels' alpha, but for - // 16 bit png files we also need the low byte set. we'll do that here. - if (depth == 16) { - cur = a->out + stride*j; // start at the beginning of the row again - for (i=0; i < x; ++i,cur+=output_bytes) { - cur[filter_bytes+1] = 255; - } - } - } - } + raw += nk; - // we make a separate pass to expand bits to pixels; for performance, - // this could run two scanlines behind the above code, so it won't - // intefere with filtering but will still be in the cache. - if (depth < 8) { - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; - // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit - // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + // expand decoded bits in cur to dest, also adding an extra alpha channel if desired + if (depth < 8) { stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + stbi_uc *in = cur; + stbi_uc *out = dest; + stbi_uc inb = 0; + stbi__uint32 nsmp = x*img_n; - // note that the final byte might overshoot and write more data than desired. - // we can allocate enough data that this never writes out of memory, but it - // could also overwrite the next scanline. can it overwrite non-empty data - // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. - // so we need to explicitly clamp the final ones - + // expand bits to bytes first if (depth == 4) { - for (k=x*img_n; k >= 2; k-=2, ++in) { - *cur++ = scale * ((*in >> 4) ); - *cur++ = scale * ((*in ) & 0x0f); + for (i=0; i < nsmp; ++i) { + if ((i & 1) == 0) inb = *in++; + *out++ = scale * (inb >> 4); + inb <<= 4; } - if (k > 0) *cur++ = scale * ((*in >> 4) ); } else if (depth == 2) { - for (k=x*img_n; k >= 4; k-=4, ++in) { - *cur++ = scale * ((*in >> 6) ); - *cur++ = scale * ((*in >> 4) & 0x03); - *cur++ = scale * ((*in >> 2) & 0x03); - *cur++ = scale * ((*in ) & 0x03); + for (i=0; i < nsmp; ++i) { + if ((i & 3) == 0) inb = *in++; + *out++ = scale * (inb >> 6); + inb <<= 2; } - if (k > 0) *cur++ = scale * ((*in >> 6) ); - if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); - if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); - } else if (depth == 1) { - for (k=x*img_n; k >= 8; k-=8, ++in) { - *cur++ = scale * ((*in >> 7) ); - *cur++ = scale * ((*in >> 6) & 0x01); - *cur++ = scale * ((*in >> 5) & 0x01); - *cur++ = scale * ((*in >> 4) & 0x01); - *cur++ = scale * ((*in >> 3) & 0x01); - *cur++ = scale * ((*in >> 2) & 0x01); - *cur++ = scale * ((*in >> 1) & 0x01); - *cur++ = scale * ((*in ) & 0x01); + } else { + STBI_ASSERT(depth == 1); + for (i=0; i < nsmp; ++i) { + if ((i & 7) == 0) inb = *in++; + *out++ = scale * (inb >> 7); + inb <<= 1; } - if (k > 0) *cur++ = scale * ((*in >> 7) ); - if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); - if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); - if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); - if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); - if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); - if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); } - if (img_n != out_n) { - int q; - // insert alpha = 255 - cur = a->out + stride*j; + + // insert alpha=255 values if desired + if (img_n != out_n) + stbi__create_png_alpha_expand8(dest, dest, x, img_n); + } else if (depth == 8) { + if (img_n == out_n) + memcpy(dest, cur, x*img_n); + else + stbi__create_png_alpha_expand8(dest, cur, x, img_n); + } else if (depth == 16) { + // convert the image data from big-endian to platform-native + stbi__uint16 *dest16 = (stbi__uint16*)dest; + stbi__uint32 nsmp = x*img_n; + + if (img_n == out_n) { + for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) + *dest16 = (cur[0] << 8) | cur[1]; + } else { + STBI_ASSERT(img_n+1 == out_n); if (img_n == 1) { - for (q=x-1; q >= 0; --q) { - cur[q*2+1] = 255; - cur[q*2+0] = cur[q]; + for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = 0xffff; } } else { STBI_ASSERT(img_n == 3); - for (q=x-1; q >= 0; --q) { - cur[q*4+3] = 255; - cur[q*4+2] = cur[q*3+2]; - cur[q*4+1] = cur[q*3+1]; - cur[q*4+0] = cur[q*3+0]; + for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = (cur[2] << 8) | cur[3]; + dest16[2] = (cur[4] << 8) | cur[5]; + dest16[3] = 0xffff; } } } } - } else if (depth == 16) { - // force the image data from big-endian to platform-native. - // this is done in a separate pass due to the decoding relying - // on the data being untouched, but could probably be done - // per-line during decode if care is taken. - stbi_uc *cur = a->out; - stbi__uint16 *cur16 = (stbi__uint16*)cur; - - for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { - *cur16 = (cur[0] << 8) | cur[1]; - } } + STBI_FREE(filter_buf); + if (!all_ok) return 0; + return 1; } @@ -5161,9 +5160,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning + tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is } else { - for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + for (k = 0; k < s->img_n && k < 3; ++k) + tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger } } break; From a45fe436dcb7648470c3967b4b5b39644f063c5d Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Mon, 9 Dec 2024 18:26:10 +0100 Subject: [PATCH 11/87] Added new GrowHorizontalLayout and GrowVerticalLayout widgets --- changelog.md | 6 + include/TGUI/AllWidgets.hpp | 2 + include/TGUI/String.hpp | 4 + include/TGUI/Widgets/GrowHorizontalLayout.hpp | 144 ++++++++++++++ include/TGUI/Widgets/GrowVerticalLayout.hpp | 144 ++++++++++++++ include/TGUI/Widgets/HorizontalLayout.hpp | 3 + include/TGUI/Widgets/VerticalLayout.hpp | 3 + src/CMakeLists.txt | 125 ++++++------ src/FileDialogIconLoaderLinux.cpp | 4 +- src/Loading/ThemeLoader.cpp | 2 +- src/Loading/WidgetFactory.cpp | 2 + src/Widgets/ButtonBase.cpp | 2 +- src/Widgets/GrowHorizontalLayout.cpp | 184 ++++++++++++++++++ src/Widgets/GrowVerticalLayout.cpp | 184 ++++++++++++++++++ tests/CMakeLists.txt | 2 + tests/Widgets/GrowHorizontalLayout.cpp | 89 +++++++++ tests/Widgets/GrowVerticalLayout.cpp | 89 +++++++++ 17 files changed, 925 insertions(+), 64 deletions(-) create mode 100644 include/TGUI/Widgets/GrowHorizontalLayout.hpp create mode 100644 include/TGUI/Widgets/GrowVerticalLayout.hpp create mode 100644 src/Widgets/GrowHorizontalLayout.cpp create mode 100644 src/Widgets/GrowVerticalLayout.cpp create mode 100644 tests/Widgets/GrowHorizontalLayout.cpp create mode 100644 tests/Widgets/GrowVerticalLayout.cpp diff --git a/changelog.md b/changelog.md index 90b028cfd..16b33803f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +TGUI 1.7 (TBD) +--------------- + +- New widgets: GrowHorizontalLayout and GrowVerticalLayout + + TGUI 1.6.1 (8 October 2024) ---------------------------- diff --git a/include/TGUI/AllWidgets.hpp b/include/TGUI/AllWidgets.hpp index 108eeb5b8..d5d25b27e 100644 --- a/include/TGUI/AllWidgets.hpp +++ b/include/TGUI/AllWidgets.hpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/include/TGUI/String.hpp b/include/TGUI/String.hpp index 26be30d0a..8c745939a 100644 --- a/include/TGUI/String.hpp +++ b/include/TGUI/String.hpp @@ -441,7 +441,11 @@ TGUI_MODULE_EXPORT namespace tgui #if TGUI_HAS_WINDOW_BACKEND_SFML // This constructor has to be explicit or it will cause MSVC to no longer compile code that performs sf::String + std::string explicit String(const sf::String& str) + #if SFML_VERSION_MAJOR >= 3 + : m_string{str.toUtf32()} + #else : m_string{reinterpret_cast(str.toUtf32().c_str())} + #endif { } diff --git a/include/TGUI/Widgets/GrowHorizontalLayout.hpp b/include/TGUI/Widgets/GrowHorizontalLayout.hpp new file mode 100644 index 000000000..179e9c353 --- /dev/null +++ b/include/TGUI/Widgets/GrowHorizontalLayout.hpp @@ -0,0 +1,144 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_GROW_HORIZONTAL_LAYOUT_HPP +#define TGUI_GROW_HORIZONTAL_LAYOUT_HPP + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Container that automatically positions children beside each other. + /// + /// The width of child widgets isn't altered, while the height is changed to match that of the horizontal layout. + /// With each widget that gets added, the width of the horizontal layout increases to fit the new widget. + /// + /// If you want the layout to have a fixed size and want children resized to fill the area then check HorizontalLayout instead. + /// + /// @since TGUI 1.7 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API GrowHorizontalLayout : public BoxLayout + { + public: + using Ptr = std::shared_ptr; //!< Shared widget pointer + using ConstPtr = std::shared_ptr; //!< Shared constant widget pointer + + static constexpr const char StaticWidgetType[] = "GrowHorizontalLayout"; //!< Type name of the widget + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Constructor + /// @param typeName Type of the widget + /// @param initRenderer Should the renderer be initialized? Should be true unless a derived class initializes it. + /// @see create + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowHorizontalLayout(const char* typeName = StaticWidgetType, bool initRenderer = true); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Copy constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowHorizontalLayout(const GrowHorizontalLayout&); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Move constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowHorizontalLayout(GrowHorizontalLayout&&) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Overload of copy assignment operator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowHorizontalLayout& operator=(const GrowHorizontalLayout&); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Move assignment + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowHorizontalLayout& operator=(GrowHorizontalLayout&&) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Destructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ~GrowHorizontalLayout() = default; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Creates a new horizontal layout widget + /// + /// @param height Height of the horizontal layout + /// + /// @return The new horizontal layout + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static GrowHorizontalLayout::Ptr create(const Layout& width = {RelativeValue(1)}); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Makes a copy of another layout + /// + /// @param layout The other layout + /// + /// @return The new layout + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static GrowHorizontalLayout::Ptr copy(const GrowHorizontalLayout::ConstPtr& layout); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the space available for widgets inside the container + /// @return Size of the container + /// + /// @warning The width returned by this function is always 0. This is to prevent child widgets from depending on the + /// width of the horizontal layout (which isn't allowed as the width of the layout depends on its children). + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f getInnerSize() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes all widgets that were added to the container + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void removeAllWidgets() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // @brief Repositions and resize the widgets + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void updateWidgets() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // @brief Makes a copy of the widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Widget::Ptr clone() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + std::vector m_widgetLayouts; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_GROW_HORIZONTAL_LAYOUT_HPP diff --git a/include/TGUI/Widgets/GrowVerticalLayout.hpp b/include/TGUI/Widgets/GrowVerticalLayout.hpp new file mode 100644 index 000000000..b3e3217c1 --- /dev/null +++ b/include/TGUI/Widgets/GrowVerticalLayout.hpp @@ -0,0 +1,144 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_GROW_VERTICAL_LAYOUT_HPP +#define TGUI_GROW_VERTICAL_LAYOUT_HPP + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Container that automatically positions children below each other. + /// + /// The height of child widgets isn't altered, while the width is changed to match that of the vertical layout. + /// With each widget that gets added, the height of the vertical layout increases to fit the new widget. + /// + /// If you want the layout to have a fixed size and want children resized to fill the area then check VerticalLayout instead. + /// + /// @since TGUI 1.7 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API GrowVerticalLayout : public BoxLayout + { + public: + using Ptr = std::shared_ptr; //!< Shared widget pointer + using ConstPtr = std::shared_ptr; //!< Shared constant widget pointer + + static constexpr const char StaticWidgetType[] = "GrowVerticalLayout"; //!< Type name of the widget + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Constructor + /// @param typeName Type of the widget + /// @param initRenderer Should the renderer be initialized? Should be true unless a derived class initializes it. + /// @see create + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowVerticalLayout(const char* typeName = StaticWidgetType, bool initRenderer = true); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Copy constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowVerticalLayout(const GrowVerticalLayout&); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Move constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowVerticalLayout(GrowVerticalLayout&&) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Overload of copy assignment operator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowVerticalLayout& operator=(const GrowVerticalLayout&); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Move assignment + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + GrowVerticalLayout& operator=(GrowVerticalLayout&&) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Destructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ~GrowVerticalLayout() = default; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Creates a new vertical layout widget + /// + /// @param width Width of the vertical layout + /// + /// @return The new vertical layout + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static GrowVerticalLayout::Ptr create(const Layout& width = {RelativeValue(1)}); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Makes a copy of another layout + /// + /// @param layout The other layout + /// + /// @return The new layout + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static GrowVerticalLayout::Ptr copy(const GrowVerticalLayout::ConstPtr& layout); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the space available for widgets inside the container + /// @return Size of the container + /// + /// @warning The height returned by this function is always 0. This is to prevent child widgets from depending on the + /// height of the vertical layout (which isn't allowed as the height of the layout depends on its children). + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f getInnerSize() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes all widgets that were added to the container + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void removeAllWidgets() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // @brief Repositions and resize the widgets + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void updateWidgets() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // @brief Makes a copy of the widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Widget::Ptr clone() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + std::vector m_widgetLayouts; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_GROW_VERTICAL_LAYOUT_HPP diff --git a/include/TGUI/Widgets/HorizontalLayout.hpp b/include/TGUI/Widgets/HorizontalLayout.hpp index 38074620d..e65ae21b3 100644 --- a/include/TGUI/Widgets/HorizontalLayout.hpp +++ b/include/TGUI/Widgets/HorizontalLayout.hpp @@ -35,6 +35,9 @@ TGUI_MODULE_EXPORT namespace tgui /// @brief Container that automatically resizes children to fit the entire available space between children. /// /// The children are positioned side by side. + /// + /// If you don't want the width of child widgets to be altered and instead want the horizontal layout to grow in size as new + /// widgets are added, then check out the GrowHorizontalLayout instead. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class TGUI_API HorizontalLayout : public BoxLayoutRatios { diff --git a/include/TGUI/Widgets/VerticalLayout.hpp b/include/TGUI/Widgets/VerticalLayout.hpp index 1af33d390..4dcb6a2b5 100644 --- a/include/TGUI/Widgets/VerticalLayout.hpp +++ b/include/TGUI/Widgets/VerticalLayout.hpp @@ -35,6 +35,9 @@ TGUI_MODULE_EXPORT namespace tgui /// @brief Container that automatically resizes children to fit the entire available space between children /// /// The children are stacked vertically. + /// + /// If you don't want the height of child widgets to be altered and instead want the vertical layout to grow in size as new + /// widgets are added, then check out the GrowVerticalLayout instead. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class TGUI_API VerticalLayout : public BoxLayoutRatios { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2bf062699..38ab6daeb 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,6 +111,8 @@ set(TGUI_SRC Widgets/FileDialog.cpp Widgets/Group.cpp Widgets/Grid.cpp + Widgets/GrowHorizontalLayout.cpp + Widgets/GrowVerticalLayout.cpp Widgets/HorizontalLayout.cpp Widgets/HorizontalWrap.cpp Widgets/Knob.cpp @@ -248,97 +250,100 @@ set(TGUI_HEADERS "${PROJECT_SOURCE_DIR}/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/DataIO.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/Deserializer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/ImageLoader.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/Serializer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/ThemeLoader.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/Theme.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/DataIO.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/Deserializer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/ThemeLoader.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Loading/WidgetFactory.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/BoxLayoutRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ButtonRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ChatBoxRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/CheckBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ChildWindowRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ColorPickerRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ComboBoxRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/EditBoxRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/FileDialogRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/GroupRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/KnobRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/LabelRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ListBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ListViewRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ProgressBarRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MenuBarRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MessageBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PictureRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ChatBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/KnobRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ButtonRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ComboBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TextAreaRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PanelListBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PanelRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/BoxLayoutRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TreeViewRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/LabelRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/WidgetRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/GroupRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/EditBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/RangeSliderRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/SplitContainerRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/FileDialogRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PictureRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ProgressBarRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/RadioButtonRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/RangeSliderRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ScrollablePanelRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ScrollbarRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TabsRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/SeparatorLineRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/SliderRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/SpinButtonRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/SplitContainerRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TabsRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TextAreaRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TextBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/CheckBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ColorPickerRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ListBoxRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MenuBarRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ScrollablePanelRenderer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ComboBox.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/VerticalLayout.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MessageBox.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Group.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/FileDialog.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Knob.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ButtonBase.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/TreeViewRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/WidgetRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/BitmapButton.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RangeSlider.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/BoxLayout.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/BoxLayoutRatios.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ButtonBase.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Button.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SpinControl.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/CanvasBase.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RadioButtonGroup.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ToggleButton.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ChatBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/CheckBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ChildWindow.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ClickableWidget.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ColorPicker.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ComboBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBoxSlider.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/FileDialog.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Grid.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Group.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/GrowHorizontalLayout.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/GrowVerticalLayout.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/HorizontalLayout.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/HorizontalWrap.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Knob.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Label.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ListBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ListView.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/HorizontalWrap.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ClickableWidget.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MenuBar.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SeparatorLine.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ColorPicker.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/CheckBox.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Scrollbar.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/PanelListBox.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/TreeView.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Label.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MessageBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Panel.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/BoxLayoutRatios.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/PanelListBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Picture.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SpinButton.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SplitContainer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBox.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ChatBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ProgressBar.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RadioButtonGroup.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RadioButton.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Slider.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RangeSlider.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RichTextLabel.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ScrollablePanel.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Scrollbar.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SeparatorLine.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Slider.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SpinButton.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SpinControl.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/SplitContainer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/TabContainer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Tabs.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/BoxLayout.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/HorizontalLayout.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/TextArea.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/TabContainer.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ChildWindow.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/RichTextLabel.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ProgressBar.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBoxSlider.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeWindows.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ToggleButton.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/TreeView.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/VerticalLayout.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeNanoSVG.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeSDL.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeStbImage.hpp" - "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeNanoSVG.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeStbImageWrite.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/extlibs/IncludeWindows.hpp" + ) if(TGUI_OS_WINDOWS) diff --git a/src/FileDialogIconLoaderLinux.cpp b/src/FileDialogIconLoaderLinux.cpp index f31e51a30..df9865ce3 100644 --- a/src/FileDialogIconLoaderLinux.cpp +++ b/src/FileDialogIconLoaderLinux.cpp @@ -425,7 +425,7 @@ namespace tgui Filesystem::Path("/usr/share/icons/hicolor/48x48/places/"), }; - std::map> foundIcons; + std::map> foundIcons; for (std::size_t i = 0; i < potentialIconPaths.size(); ++i) { const Filesystem::Path& iconDir = potentialIconPaths[i]; @@ -449,7 +449,7 @@ namespace tgui continue; // If both an SVG and a PNG file exist then we will select the svg file - int themeIconPriority = 10 * themePriority; + std::size_t themeIconPriority = 10 * themePriority; if (isSvg) themeIconPriority += 2; else if (isPng) diff --git a/src/Loading/ThemeLoader.cpp b/src/Loading/ThemeLoader.cpp index aa38ff75e..262045ec9 100644 --- a/src/Loading/ThemeLoader.cpp +++ b/src/Loading/ThemeLoader.cpp @@ -269,7 +269,7 @@ namespace tgui throw Exception{U"Failed to open theme file '" + fullFilename + U"'."}; std::stringstream stream; - stream.write(reinterpret_cast(fileContents.get()), static_cast(fileSize)); + stream.write(reinterpret_cast(fileContents.get()), static_cast(fileSize)); std::unique_ptr root = DataIO::parse(stream); diff --git a/src/Loading/WidgetFactory.cpp b/src/Loading/WidgetFactory.cpp index cf37a0e8b..340454024 100644 --- a/src/Loading/WidgetFactory.cpp +++ b/src/Loading/WidgetFactory.cpp @@ -44,6 +44,8 @@ namespace tgui {"FileDialog", std::make_shared}, {"Grid", std::make_shared}, {"Group", std::make_shared}, + {"GrowHorizontalLayout", std::make_shared}, + {"GrowVerticalLayout", std::make_shared}, {"HorizontalLayout", std::make_shared}, {"HorizontalWrap", std::make_shared}, {"Knob", std::make_shared}, diff --git a/src/Widgets/ButtonBase.cpp b/src/Widgets/ButtonBase.cpp index 820a21394..89d9893e1 100644 --- a/src/Widgets/ButtonBase.cpp +++ b/src/Widgets/ButtonBase.cpp @@ -138,7 +138,7 @@ namespace tgui { text.style.disconnectCallback(m_textStyleChangedCallbackId); - ClickableWidget::operator=(other); + ClickableWidget::operator=(std::move(other)); m_string = std::move(other.m_string); m_down = std::move(other.m_down); m_state = std::move(other.m_state); diff --git a/src/Widgets/GrowHorizontalLayout.cpp b/src/Widgets/GrowHorizontalLayout.cpp new file mode 100644 index 000000000..97124e1ef --- /dev/null +++ b/src/Widgets/GrowHorizontalLayout.cpp @@ -0,0 +1,184 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace tgui +{ +#if TGUI_COMPILED_WITH_CPP_VER < 17 + constexpr const char GrowHorizontalLayout::StaticWidgetType[]; +#endif + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout::GrowHorizontalLayout(const char* typeName, bool initRenderer) : + BoxLayout{typeName, false} + { + if (initRenderer) + { + m_renderer = aurora::makeCopied(); + setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout::GrowHorizontalLayout(const GrowHorizontalLayout& other) : + BoxLayout {other}, + m_widgetLayouts{} + { + GrowHorizontalLayout::updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout::GrowHorizontalLayout(GrowHorizontalLayout&& other) noexcept : + BoxLayout {std::move(other)}, + m_widgetLayouts{} + { + GrowHorizontalLayout::updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout& GrowHorizontalLayout::operator=(const GrowHorizontalLayout& other) + { + if (&other != this) + { + BoxLayout::operator=(other); + m_widgetLayouts = {}; + + GrowHorizontalLayout::updateWidgets(); + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout& GrowHorizontalLayout::operator=(GrowHorizontalLayout&& other) noexcept + { + if (&other != this) + { + BoxLayout::operator=(std::move(other)); + m_widgetLayouts = {}; + + GrowHorizontalLayout::updateWidgets(); + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout::Ptr GrowHorizontalLayout::create(const Layout& width) + { + auto layout = std::make_shared(); + layout->setWidth(width); + return layout; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowHorizontalLayout::Ptr GrowHorizontalLayout::copy(const GrowHorizontalLayout::ConstPtr& layout) + { + if (layout) + return std::static_pointer_cast(layout->clone()); + else + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void GrowHorizontalLayout::updateWidgets() + { + m_widgetLayouts.clear(); + + const float contentHeight = std::max(0.f, getSize().y - m_paddingCached.getTop() - m_paddingCached.getBottom()); + + float currentOffset = 0; + for (const auto& widget : m_widgets) + { + widget->setPosition({currentOffset, 0}); + widget->setHeight(contentHeight); + + // Correct the size for widgets that are bigger than what you set (e.g. have borders around it or a text next to them) + if (widget->getFullSize() != widget->getSize()) + { + const float newHeight = widget->getSize().y - (widget->getFullSize().y - widget->getSize().y); + if (newHeight > 0) + { + widget->setHeight(newHeight); + widget->setPosition(widget->getPosition() - widget->getWidgetOffset()); + } + } + + currentOffset += widget->getFullSize().x + m_spaceBetweenWidgetsCached; + } + + float layoutWidth = currentOffset + m_paddingCached.getLeft() + m_paddingCached.getRight(); + if (!m_widgets.empty()) + layoutWidth -= m_spaceBetweenWidgetsCached; // There is no padding below the last widget + + // Call the function from Widget instead of BoxLayout to prevent an infinite loop + // NOLINTNEXTLINE(bugprone-parent-virtual-call) + Widget::setSize({layoutWidth, getSizeLayout().y}); + + // Bind layouts to the child widgets so that we can recalculate the positions when the width of one of them changes + m_widgetLayouts.reserve(m_widgets.size()); + for (const auto& widget : m_widgets) + { + m_widgetLayouts.push_back(bindWidth(widget)); + m_widgetLayouts.back().connectWidget(this, true, [this]{ updateWidgets(); }); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Widget::Ptr GrowHorizontalLayout::clone() const + { + return std::make_shared(*this); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Vector2f GrowHorizontalLayout::getInnerSize() const + { + return {0.f, BoxLayout::getInnerSize().y}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void GrowHorizontalLayout::removeAllWidgets() + { + BoxLayout::removeAllWidgets(); + updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/GrowVerticalLayout.cpp b/src/Widgets/GrowVerticalLayout.cpp new file mode 100644 index 000000000..20731ed49 --- /dev/null +++ b/src/Widgets/GrowVerticalLayout.cpp @@ -0,0 +1,184 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace tgui +{ +#if TGUI_COMPILED_WITH_CPP_VER < 17 + constexpr const char GrowVerticalLayout::StaticWidgetType[]; +#endif + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout::GrowVerticalLayout(const char* typeName, bool initRenderer) : + BoxLayout{typeName, false} + { + if (initRenderer) + { + m_renderer = aurora::makeCopied(); + setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout::GrowVerticalLayout(const GrowVerticalLayout& other) : + BoxLayout {other}, + m_widgetLayouts{} + { + GrowVerticalLayout::updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout::GrowVerticalLayout(GrowVerticalLayout&& other) noexcept : + BoxLayout {std::move(other)}, + m_widgetLayouts{} + { + GrowVerticalLayout::updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout& GrowVerticalLayout::operator=(const GrowVerticalLayout& other) + { + if (&other != this) + { + BoxLayout::operator=(other); + m_widgetLayouts = {}; + + GrowVerticalLayout::updateWidgets(); + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout& GrowVerticalLayout::operator=(GrowVerticalLayout&& other) noexcept + { + if (&other != this) + { + BoxLayout::operator=(std::move(other)); + m_widgetLayouts = {}; + + GrowVerticalLayout::updateWidgets(); + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout::Ptr GrowVerticalLayout::create(const Layout& width) + { + auto layout = std::make_shared(); + layout->setWidth(width); + return layout; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + GrowVerticalLayout::Ptr GrowVerticalLayout::copy(const GrowVerticalLayout::ConstPtr& layout) + { + if (layout) + return std::static_pointer_cast(layout->clone()); + else + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void GrowVerticalLayout::updateWidgets() + { + m_widgetLayouts.clear(); + + const float contentWidth = std::max(0.f, getSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight()); + + float currentOffset = 0; + for (const auto& widget : m_widgets) + { + widget->setPosition({0, currentOffset}); + widget->setWidth(contentWidth); + + // Correct the size for widgets that are bigger than what you set (e.g. have borders around it or a text next to them) + if (widget->getFullSize().x != widget->getSize().x) + { + const float newWidth = widget->getSize().x - (widget->getFullSize().x - widget->getSize().x); + if (newWidth > 0) + { + widget->setWidth(newWidth); + widget->setPosition(widget->getPosition() - widget->getWidgetOffset()); + } + } + + currentOffset += widget->getFullSize().y + m_spaceBetweenWidgetsCached; + } + + float layoutHeight = currentOffset + m_paddingCached.getTop() + m_paddingCached.getBottom(); + if (!m_widgets.empty()) + layoutHeight -= m_spaceBetweenWidgetsCached; // There is no padding below the last widget + + // Call the function from Widget instead of BoxLayout to prevent an infinite loop + // NOLINTNEXTLINE(bugprone-parent-virtual-call) + Widget::setSize({getSizeLayout().x, layoutHeight}); + + // Bind layouts to the child widgets so that we can recalculate the positions when the height of one of them changes + m_widgetLayouts.reserve(m_widgets.size()); + for (const auto& widget : m_widgets) + { + m_widgetLayouts.push_back(bindHeight(widget)); + m_widgetLayouts.back().connectWidget(this, false, [this]{ updateWidgets(); }); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Widget::Ptr GrowVerticalLayout::clone() const + { + return std::make_shared(*this); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Vector2f GrowVerticalLayout::getInnerSize() const + { + return {BoxLayout::getInnerSize().x, 0.f}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void GrowVerticalLayout::removeAllWidgets() + { + BoxLayout::removeAllWidgets(); + updateWidgets(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 77462242c..e5700a37a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -71,6 +71,8 @@ set(TEST_SOURCES Widgets/FileDialog.cpp Widgets/Group.cpp Widgets/Grid.cpp + Widgets/GrowHorizontalLayout.cpp + Widgets/GrowVerticalLayout.cpp Widgets/HorizontalLayout.cpp Widgets/HorizontalWrap.cpp Widgets/Knob.cpp diff --git a/tests/Widgets/GrowHorizontalLayout.cpp b/tests/Widgets/GrowHorizontalLayout.cpp new file mode 100644 index 000000000..31b042590 --- /dev/null +++ b/tests/Widgets/GrowHorizontalLayout.cpp @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Tests.hpp" + +TEST_CASE("[GrowHorizontalLayout]") +{ + auto layout = tgui::GrowHorizontalLayout::create(); + layout->setHeight(300); + layout->setPosition(50, 40); + + SECTION("Positions and sizes") + { + REQUIRE(layout->getSize() == tgui::Vector2f{0, 300}); + + layout->getRenderer()->setSpaceBetweenWidgets(10); + layout->setSize(300, 300); + REQUIRE(layout->getSize() == tgui::Vector2f{0, 300}); + + auto button = tgui::Button::create("Hello"); + button->setWidth(50); + layout->add(button, "Btn"); + + REQUIRE(layout->getSize() == tgui::Vector2f{50, 300}); + + auto panel = tgui::Panel::create(); + layout->add(panel); + panel->setWidth(30); + + REQUIRE(layout->getSize() == tgui::Vector2f{90, 300}); + + auto button2 = tgui::Button::create("World"); + button2->setWidth("height * 0.4"); + layout->add(button2); + + REQUIRE(layout->getSize() == tgui::Vector2f{220, 300}); + + auto editBox = tgui::EditBox::create(); + editBox->setWidth(20); + layout->insert(1, editBox); + + REQUIRE(layout->getSize() == tgui::Vector2f{250, 300}); + + layout->remove(panel); + + REQUIRE(layout->getSize() == tgui::Vector2f{210, 300}); + + layout->setHeight(350); + REQUIRE(layout->getSize() == tgui::Vector2f{230, 350}); + + auto layout2 = tgui::GrowHorizontalLayout::copy(layout); + + layout2->get("Btn")->setWidth(100); + REQUIRE(layout->getSize() == tgui::Vector2f{230, 350}); + REQUIRE(layout2->getSize() == tgui::Vector2f{280, 350}); + + layout->removeAllWidgets(); + REQUIRE(layout->getSize() == tgui::Vector2f{0, 350}); + REQUIRE(layout2->getSize() == tgui::Vector2f{280, 350}); + } + + SECTION("Saving and loading from file") + { + layout->add(tgui::Button::create("Hello")); + layout->add(tgui::Button::create("World")); + testSavingWidget("GrowHorizontalLayout", layout, false); + } +} diff --git a/tests/Widgets/GrowVerticalLayout.cpp b/tests/Widgets/GrowVerticalLayout.cpp new file mode 100644 index 000000000..5cf16acab --- /dev/null +++ b/tests/Widgets/GrowVerticalLayout.cpp @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Tests.hpp" + +TEST_CASE("[GrowVerticalLayout]") +{ + auto layout = tgui::GrowVerticalLayout::create(); + layout->setWidth(300); + layout->setPosition(50, 40); + + SECTION("Positions and sizes") + { + REQUIRE(layout->getSize() == tgui::Vector2f{300, 0}); + + layout->getRenderer()->setSpaceBetweenWidgets(10); + layout->setSize(300, 300); + REQUIRE(layout->getSize() == tgui::Vector2f{300, 0}); + + auto button = tgui::Button::create("Hello"); + button->setHeight(50); + layout->add(button, "Btn"); + + REQUIRE(layout->getSize() == tgui::Vector2f{300, 50}); + + auto panel = tgui::Panel::create(); + layout->add(panel); + panel->setHeight(30); + + REQUIRE(layout->getSize() == tgui::Vector2f{300, 90}); + + auto button2 = tgui::Button::create("World"); + button2->setHeight("width * 0.4"); + layout->add(button2); + + REQUIRE(layout->getSize() == tgui::Vector2f{300, 220}); + + auto editBox = tgui::EditBox::create(); + editBox->setHeight(20); + layout->insert(1, editBox); + + REQUIRE(layout->getSize() == tgui::Vector2f{300, 250}); + + layout->remove(panel); + + REQUIRE(layout->getSize() == tgui::Vector2f{300, 210}); + + layout->setWidth(350); + REQUIRE(layout->getSize() == tgui::Vector2f{350, 230}); + + auto layout2 = tgui::GrowVerticalLayout::copy(layout); + + layout2->get("Btn")->setHeight(100); + REQUIRE(layout->getSize() == tgui::Vector2f{350, 230}); + REQUIRE(layout2->getSize() == tgui::Vector2f{350, 280}); + + layout->removeAllWidgets(); + REQUIRE(layout->getSize() == tgui::Vector2f{350, 0}); + REQUIRE(layout2->getSize() == tgui::Vector2f{350, 280}); + } + + SECTION("Saving and loading from file") + { + layout->add(tgui::Button::create("Hello")); + layout->add(tgui::Button::create("World")); + testSavingWidget("GrowVerticalLayout", layout, false); + } +} From f631a4fc88f53b7e05c0d3d0760cf4e514f431f8 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 19 Dec 2024 15:18:25 +0100 Subject: [PATCH 12/87] Fixed wrong parameter in GrowHorizontalLayout::create --- include/TGUI/Widgets/GrowHorizontalLayout.hpp | 2 +- src/Widgets/GrowHorizontalLayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/TGUI/Widgets/GrowHorizontalLayout.hpp b/include/TGUI/Widgets/GrowHorizontalLayout.hpp index 179e9c353..ca150adf9 100644 --- a/include/TGUI/Widgets/GrowHorizontalLayout.hpp +++ b/include/TGUI/Widgets/GrowHorizontalLayout.hpp @@ -90,7 +90,7 @@ TGUI_MODULE_EXPORT namespace tgui /// /// @return The new horizontal layout ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD static GrowHorizontalLayout::Ptr create(const Layout& width = {RelativeValue(1)}); + TGUI_NODISCARD static GrowHorizontalLayout::Ptr create(const Layout& height = {RelativeValue(1)}); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Makes a copy of another layout diff --git a/src/Widgets/GrowHorizontalLayout.cpp b/src/Widgets/GrowHorizontalLayout.cpp index 97124e1ef..00e0c31d0 100644 --- a/src/Widgets/GrowHorizontalLayout.cpp +++ b/src/Widgets/GrowHorizontalLayout.cpp @@ -94,10 +94,10 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - GrowHorizontalLayout::Ptr GrowHorizontalLayout::create(const Layout& width) + GrowHorizontalLayout::Ptr GrowHorizontalLayout::create(const Layout& height) { auto layout = std::make_shared(); - layout->setWidth(width); + layout->setHeight(height); return layout; } From 9320e0070efd705fc6704fabcbd5e9c7bfe0cf24 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 19 Dec 2024 15:19:26 +0100 Subject: [PATCH 13/87] Font ascent and descent were wrong in SFML backend when font scale was set --- src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp index 87cde913e..d1d34d9fb 100644 --- a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp +++ b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp @@ -178,9 +178,9 @@ namespace tgui if (!m_font->hasGlyph(U'\u00CA')) return static_cast(scaledTextSize) / m_fontScale; - const FontGlyph& glyph = getGlyph(U'\u00CA', scaledTextSize, false, 0); + const FontGlyph& glyph = getGlyph(U'\u00CA', characterSize, false, 0); #else - const FontGlyph& glyph = getGlyph(U'\u00CA', scaledTextSize, false, 0); + const FontGlyph& glyph = getGlyph(U'\u00CA', characterSize, false, 0); if ((glyph.advance == 0) && (glyph.bounds == FloatRect{}) && (glyph.textureRect == UIntRect{})) return static_cast(scaledTextSize) / m_fontScale; #endif @@ -194,8 +194,7 @@ namespace tgui { // SFML doesn't provide a method to access the descent of the font. // We extract the descent by examining the 'g' glyph, assuming it exists. - const unsigned int scaledTextSize = static_cast(characterSize * m_fontScale); - const FontGlyph& glyph = getGlyph(U'g', scaledTextSize, false); + const FontGlyph& glyph = getGlyph(U'g', characterSize, false); return glyph.bounds.height + glyph.bounds.top; } From fd59d6a6ae0a9fbcc7ecf2b7ef550f703b0ac035 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 19 Dec 2024 16:14:26 +0100 Subject: [PATCH 14/87] Fixed possible corrupted text when changing the font scale with the SFML backend --- changelog.md | 1 + .../Font/SFML-Graphics/BackendFontSFML.hpp | 4 ++++ .../Font/SFML-Graphics/BackendFontSFML.cpp | 3 ++- tests/Widget.cpp | 22 ++++++++++++++++++ tests/expected/FontScale_Scaled.png | Bin 0 -> 8867 bytes tests/expected/FontScale_Unscaled.png | Bin 0 -> 14713 bytes 6 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/expected/FontScale_Scaled.png create mode 100644 tests/expected/FontScale_Unscaled.png diff --git a/changelog.md b/changelog.md index 16b33803f..25b258f9f 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ TGUI 1.7 (TBD) --------------- - New widgets: GrowHorizontalLayout and GrowVerticalLayout +- Fixed some issues with font scale in SFML font backend TGUI 1.6.1 (8 October 2024) diff --git a/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp b/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp index 72abf28a2..3482bf985 100644 --- a/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp +++ b/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp @@ -218,6 +218,10 @@ TGUI_MODULE_EXPORT namespace tgui // from breaking since sf::Font does the same. std::map> m_textures; std::map m_textureVersions; + + // We use a single version that is unique across all text sizes. Otherwise switching from size by changing the font scale + // can result in the same version being accidentally returned and the text not realizing that the texture changed. + unsigned int m_lastTextureVersion = 0; }; } diff --git a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp index d1d34d9fb..2bf87040b 100644 --- a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp +++ b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp @@ -243,7 +243,8 @@ namespace tgui } m_textures[scaledTextSize] = texture; - textureVersion = ++m_textureVersions[scaledTextSize]; + textureVersion = ++m_lastTextureVersion; + m_textureVersions[scaledTextSize] = textureVersion; return texture; } diff --git a/tests/Widget.cpp b/tests/Widget.cpp index c0a418d28..a813db207 100644 --- a/tests/Widget.cpp +++ b/tests/Widget.cpp @@ -639,6 +639,28 @@ TEST_CASE("[Widget]") TEST_DRAW("OriginScaleRotation.png") } + + SECTION("Font scale") + { + auto button = tgui::Button::create(); + button->setSize(150, 50); + button->setText("Scaling"); + button->setTextSize(32); + button->setPosition(5, 10); + + TEST_DRAW_INIT(400, 175, button) + + auto oldView = gui.getView(); + gui.setAbsoluteView({0, 0, 160, 70}); + + TEST_DRAW("FontScale_Unscaled.png") + + tgui::getBackend()->setFontScale(2.5f); + TEST_DRAW("FontScale_Scaled.png") + + tgui::getBackend()->setFontScale(1); + gui.setAbsoluteView(oldView.getRect()); + } } SECTION("Bug Fixes") diff --git a/tests/expected/FontScale_Scaled.png b/tests/expected/FontScale_Scaled.png new file mode 100644 index 0000000000000000000000000000000000000000..24186e23461e7f9eefa5ecf117d28da1eb318eaf GIT binary patch literal 8867 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 Date: Sat, 21 Dec 2024 11:49:53 +0100 Subject: [PATCH 15/87] Building as c++ module isn't compatible with building as DLL on Windows (it results in linking errors due to lacking dllimport) --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5bcaf0ee..fe94a0625 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,9 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) if(TGUI_CXX_STANDARD LESS 20) message(FATAL_ERROR "TGUI_BUILD_AS_CXX_MODULE can only be turned on if TGUI_CXX_STANDARD is set to at least 20") endif() + if(TGUI_OS_WINDOWS AND TGUI_SHARED_LIBS) + message(FATAL_ERROR "On Windows, BUILD_SHARED_LIBS must be OFF if TGUI_BUILD_AS_CXX_MODULE is ON") + endif() endif() endif() From 7d7165a547a4bf8dc27f2ae0ccf924003920d03c Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 10:49:16 +0100 Subject: [PATCH 16/87] Added GrowHorizontalLayout and GrowVerticalLayout to Gui Builder --- .../GrowHorizontalLayoutProperties.hpp | 35 ++++++++++++++++++ .../GrowVerticalLayoutProperties.hpp | 35 ++++++++++++++++++ .../widget-icons/GrowHorizontalLayout.png | Bin 0 -> 4757 bytes .../widget-icons/GrowVerticalLayout.png | Bin 0 -> 4754 bytes gui-builder/src/GuiBuilder.cpp | 6 +++ 5 files changed, 76 insertions(+) create mode 100644 gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp create mode 100644 gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp create mode 100644 gui-builder/resources/widget-icons/GrowHorizontalLayout.png create mode 100644 gui-builder/resources/widget-icons/GrowVerticalLayout.png diff --git a/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp new file mode 100644 index 000000000..133f971d3 --- /dev/null +++ b/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#ifndef TGUI_GUI_BUILDER_GROW_HORIZONTAL_LAYOUT_PROPERTIES_HPP +#define TGUI_GUI_BUILDER_GROW_HORIZONTAL_LAYOUT_PROPERTIES_HPP + +#include "GroupProperties.hpp" + +struct GrowHorizontalLayoutProperties : GroupProperties +{ +}; + +#endif // TGUI_GUI_BUILDER_GROW_HORIZONTAL_LAYOUT_PROPERTIES_HPP diff --git a/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp new file mode 100644 index 000000000..a700edcdc --- /dev/null +++ b/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#ifndef TGUI_GUI_BUILDER_GROW_VERTICAL_LAYOUT_PROPERTIES_HPP +#define TGUI_GUI_BUILDER_GROW_VERTICAL_LAYOUT_PROPERTIES_HPP + +#include "GroupProperties.hpp" + +struct GrowVerticalLayoutProperties : GroupProperties +{ +}; + +#endif // TGUI_GUI_BUILDER_GROW_VERTICAL_LAYOUT_PROPERTIES_HPP diff --git a/gui-builder/resources/widget-icons/GrowHorizontalLayout.png b/gui-builder/resources/widget-icons/GrowHorizontalLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..65a21e6b95788105742395e9eeab97133e885e3d GIT binary patch literal 4757 zcmeHLeQ*@z8Q%k%gviGrCL~JBx(rGpd$%9=wQDXUxjV^8E{5c!N7cc--FGira<}K* zCU=Qn;iG(L8%mJsP{syEK89&fMkthz3L@IUf>N9U+6of|I!2SBGE>wH^x3`3m(}US zDgWhm-hJPF-skzf&-;6x_nF&WQ&T-}V(y)}7=}&sReEZn|B2pmvfzF{wQCE8neIVB zpX~D$V>uwZ4FuybQ%27;WIV<+78?ulc4(7KW3aoRe+k;{AlLQvcBkn_M!yHfcV)(h zU_3jcqubM9I}!S~pfNDM1Ny&0Q&y$dy$oahmt$P+I1)4@;YmfS$LIO{HMknZ1>7%) z80Hv*8P@&1G0m81%FH?en_{dy&F~D3!=1JAj1?P$t!&T62tXeP?wUFVJvWxj+`fO! z{IS>W2D=rC+g;;xyYX0Dm6ZmBVW~||uX9x%E1Q0Nah><{a~*k}=}h3>gF9A>ofT7x zSNv@A!`bWSztQ1yw|8~T-k(3cFZg?Yzq9+Zi^Vz1X5gnLRX=C0?Yh}s@qEGLwr{TX zeEdnzkMR%Qt$LjgwQl=JE}k-tJ^%3T?!3DvY@SABNpfML{e>01*AL8VeKon@fgIRu~xTUWMf|FKzW>vH$whsw@(m-hBVd%w8Ap1ko4w)&&^ ztCj!gItJPJh!O~DL4Or5su8mwsUc)eMPf!YOXj9xg17`}cnF1+sEg=5_y&P1l8gAM z%}@DbZd9*Sw!~3gOLahOSt4>0F}F0gB*gW)& z2trc2)i}bfW~-SZy(y)MAxd-clDH)EwVnqu5b)$8>NPFKTP(?B(wt$1dQB6pZ(Zoz0B8}le2{Eq3GzC&$#}qv`7S+W5`mA5^7^yMBXM8)n*Qbki-G|SYy1w*p4Jx zPy>p9Y64cJhb^g}&jAaag0K>a8CF2{FilO72gw@dn?7S~XQ(4!K7cz+yMOP7GHChz zyhjxqb@zN87oo4uORA_yyfH)&3p+*GNLIGfq?LBiWQao|=@4u}h^Fm`b4o*?e9?p^ zL`9@S0k~NK90yC$lFcTNvM2(C$gw0RBfznWArZ02>XgMH5D&!_$V#DMs8>3a1W-1? zZe?VSBW23YfH$(8;bc6Q0K2Ld|@|`bUJevC^HDTpV z$+iFWwY7z*DNijuyzc(LIBs8jq&s-w*uhoJ!Oj=QPmSEStf(R}fBm)jMlLie&vL-t^A6xza_H!93HG?oXgqk>Jf9^OHajSU3<_m>uMc!yrb5(EnqwK z^roYQb8;3I_pRG->CGk2AODlp$1)!O}5!Zmpgda O7UuI-dv;YkzU)7{B~tDH literal 0 HcmV?d00001 diff --git a/gui-builder/resources/widget-icons/GrowVerticalLayout.png b/gui-builder/resources/widget-icons/GrowVerticalLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2189a168b601a78eaca8f8e45b1553671a83f1 GIT binary patch literal 4754 zcmeHLe{dAl9p8&U(iox$3CNGKZUiA^?{@d@_U_gkkldZ*G?xT&YN$A7Z};tGo80Yj zx5-_?Xv2>R*f!QEVu7&e&2U)cXMU=vdP&qvoQ>t>@9V#fc}SC%bEoDJE@m;Vwhn* zs`g4=Zy}ZivKv7#0W+lZ45P*wh8wUOK;8x|*N}nDg8mt3w}4#J*V;_OM7@6%#J3+t3&oPlNtX(BzHDba z0*2W#Fx`5%*QXgHO&QI0z@``rM>8Bl<8U{dIflhDut(c6F#^yhfV+nF5zqA{Q@8J5 zvu9;rC)jO}U9L*6%Y{dxiX_(~3`^{I_z7oe&(hh49;)*6J=UJ*p3V60*x$KH=qi~~ zxZ%eg_hvqM&%t)DtF6C(L3jS_E7dP@-S&a=X9}~{&BZ^=Eq~0oqW@}J$-b8gY33GV(G=CbXH^$F=1Yag1rapm&+HXqr1N7+97vx4J!kDs(wVp-AJ6osu zmzUhi?tJz9bJeANkNoZ3CHtU*Hb+rabGct=t`i(0v1D;}QGx@25K?(O5vmWzxP+6?aXA=kViSSuDr%jR zsD`9;DN%%5j20tBdJ=LYLoCk5i=v{$t#IF!f`BI{QLCyE&SZ+mM%+Tn1R zD8|GvBxsParm)H<$Z)JcgGgeyQA~)+5mkoN*D(2j(x5sC0_O2y|3VR;FAX1#rC0zy zObI?>qK%X(6f%vrh^d}N07*IYofa{FQv{h-pqSDS6_BS9h1G)55TcN_k2FN<_3em) z3Du(zsK#Jb`kE!R^O?5LCS1+ZpW$n5S{C(H`Ert_)f} zALmwt2F*RM+ev8abD|>1BBu`##Db+LD`}QknzYb1nhZFQK-zdKAE0R#Iqc#nC~r8X z@?imKPylX}0mn{B0R}OMv>_fKtc*bNHrhrCNMsolFk5&FKMJBEDnnNC^`pJgphSSO z@~nlC91c>VSO&b2SkfT^6fKC75Rj~_U9js=qQKpyL_<7;Qx5S#WQv4?`h-R}S6u0J z5{!`=kyO_6sssj3qD&4qBt|CuatKwayv8PNGh1wS%1*H?OVRe^LOR}kC>n!I)G+l* ztD9?K;b1dBEU)D$0O)eq3#XS;CF)m{dMA;t(dlU)94C=ic{kK~08LkI|8Uj*5k+%U z(tQoir--uD^xw3#!-E%rK7_nfj;TttNf#wgR25pCd`dpn%lc8mas5zmypY^NjBiBA zcmq~)N~q<-K?Kz!m9E2b`8!fUvNA)Bp1pX@+Fz|ICTh7K=<;SsV^(k?C7u zPb!S6qd-kk2K5=ry(wMqQ=Ean*YlT3x9hnCj*l-gCVt218mDVa42(&6JiEr}8WRI! zQXbE){~KM|BX5i-41e_E@IH9^rQPt_k4*~Pv&@ZM)voq8_B;uaA4E!5#^9sLRIM4X zZ98UwFjMvVJei;7w>Q zOZNT7kJaF!=dj!wW!vjh|N1-6>4)BE=}&w)bI0x8-qqOE`|sR^np%$R&B7nv_rWS( z&&s+fHRsMxZJ&JT?5z5OQ$CNsWm$i6V^{u9qUC>?eXJsXYxk@-pRRqr;?$gu-(); m_widgetProperties["EditBoxSlider"] = std::make_unique(); m_widgetProperties["Group"] = std::make_unique(); + m_widgetProperties["GrowHorizontalLayout"] = std::make_unique(); + m_widgetProperties["GrowVerticalLayout"] = std::make_unique(); m_widgetProperties["HorizontalLayout"] = std::make_unique(); m_widgetProperties["HorizontalWrap"] = std::make_unique(); m_widgetProperties["Knob"] = std::make_unique(); @@ -1057,6 +1061,8 @@ void GuiBuilder::loadToolbox() {"EditBox", []{ return tgui::EditBox::create(); }}, {"EditBoxSlider", []{ return tgui::EditBoxSlider::create(); }}, {"Group", []{ return tgui::Group::create({150, 150}); }}, + {"GrowHorizontalLayout", []{ return tgui::GrowHorizontalLayout::create(150); }}, + {"GrowVerticalLayout", []{ return tgui::GrowVerticalLayout::create(150); }}, {"HorizontalLayout", []{ return tgui::HorizontalLayout::create({150, 150}); }}, {"HorizontalWrap", []{ return tgui::HorizontalWrap::create({150, 150}); }}, {"Knob", []{ return tgui::Knob::create(); }}, From 204f2dc0b009b39990b335dba7ff01d36be10a9c Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 10:49:48 +0100 Subject: [PATCH 17/87] Make it possible to click on widgets with a width or height of 0 in the Gui Builder --- gui-builder/src/Form.cpp | 72 +++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/gui-builder/src/Form.cpp b/gui-builder/src/Form.cpp index 5b8d80bc9..35bd5a1ea 100644 --- a/gui-builder/src/Form.cpp +++ b/gui-builder/src/Form.cpp @@ -597,14 +597,20 @@ void Form::updateSelectionSquarePositions() parentWidget = parentWidget->getParent(); } - m_selectionSquares[0]->setPosition({position.x, position.y}); - m_selectionSquares[1]->setPosition({position.x + (widget->getSize().x / 2.f), position.y}); - m_selectionSquares[2]->setPosition({position.x + widget->getSize().x, position.y}); - m_selectionSquares[3]->setPosition({position.x + widget->getSize().x, position.y + (widget->getSize().y / 2.f)}); - m_selectionSquares[4]->setPosition({position.x + widget->getSize().x, position.y + widget->getSize().y}); - m_selectionSquares[5]->setPosition({position.x + (widget->getSize().x / 2.f), position.y + widget->getSize().y}); - m_selectionSquares[6]->setPosition({position.x, position.y + widget->getSize().y}); - m_selectionSquares[7]->setPosition({position.x, position.y + (widget->getSize().y / 2.f)}); + auto size = widget->getSize(); + if (std::abs(size.x) < 5) + size.x = 5; + if (std::abs(size.y) < 5) + size.y = 5; + + m_selectionSquares[0]->setPosition({position.x, position.y + (size.y / 2.f)}); // Left + m_selectionSquares[1]->setPosition({position.x + (size.x / 2.f), position.y}); // Top + m_selectionSquares[2]->setPosition({position.x + (size.x / 2.f), position.y + size.y}); // Bottom + m_selectionSquares[3]->setPosition({position.x + size.x, position.y + (size.y / 2.f)}); // Right + m_selectionSquares[4]->setPosition({position.x, position.y}); // Top left + m_selectionSquares[5]->setPosition({position.x, position.y + size.y}); // Bottom left + m_selectionSquares[6]->setPosition({position.x + size.x, position.y}); // Top right + m_selectionSquares[7]->setPosition({position.x + size.x, position.y + size.y}); // Bottom right // The positions given to the squares where those of its center for (auto& square : m_selectionSquares) @@ -1050,13 +1056,14 @@ tgui::Widget::Ptr Form::getWidgetBelowMouse(const tgui::Container::Ptr& parent, for (auto it = widgets.rbegin(); it != widgets.rend(); ++it) { tgui::Widget::Ptr widget = *it; - if (widget && tgui::FloatRect{widget->getPosition().x, widget->getPosition().y, widget->getFullSize().x, widget->getFullSize().y}.contains(pos)) - { - // Skip invisible widgets, those have to be selected using the combo box in the properties window. - // This prevents clicking on stuff you don't see instead of the thing you are trying to click on. - if (!widget->isVisible()) - continue; + // Skip invisible widgets, those have to be selected using the combo box in the properties window. + // This prevents clicking on stuff you don't see instead of the thing you are trying to click on. + if (!widget || !widget->isVisible()) + continue; + + if (tgui::FloatRect{widget->getPosition().x + widget->getWidgetOffset().x, widget->getPosition().y + widget->getWidgetOffset().y, widget->getFullSize().x, widget->getFullSize().y}.contains(pos)) + { if (widget->isContainer()) { tgui::Container::Ptr container = std::static_pointer_cast(widget); @@ -1069,6 +1076,21 @@ tgui::Widget::Ptr Form::getWidgetBelowMouse(const tgui::Container::Ptr& parent, } } + // If a widget has a width or height of 0 then we still select it if the mouse is nearby it and there was no sibling widget below the mouse + for (auto it = widgets.rbegin(); it != widgets.rend(); ++it) + { + tgui::Widget::Ptr widget = *it; + if (!widget || !widget->isVisible()) + continue; + + if (((widget->getSize().x < 5) && (widget->getSize().y < 5) && tgui::FloatRect{widget->getPosition().x - 5, widget->getPosition().y - 5, 10, 10}.contains(pos)) + || ((widget->getSize().x < 5) && tgui::FloatRect{widget->getPosition().x - 5, widget->getPosition().y, 10, widget->getSize().y}.contains(pos)) + || ((widget->getSize().y < 5) && tgui::FloatRect{widget->getPosition().x, widget->getPosition().y - 5, widget->getSize().x, 10}.contains(pos))) + { + return widget; + } + } + return nullptr; } @@ -1178,7 +1200,7 @@ void Form::onDrag(tgui::Vector2i mousePos) updated = true; } } - else if (m_draggingSelectionSquare == m_selectionSquares[5]) // Bottom + else if (m_draggingSelectionSquare == m_selectionSquares[2]) // Bottom { while (pos.y - m_draggingPos.y >= MOVE_STEP) { @@ -1194,7 +1216,7 @@ void Form::onDrag(tgui::Vector2i mousePos) updated = true; } } - else if (m_draggingSelectionSquare == m_selectionSquares[7]) // Left + else if (m_draggingSelectionSquare == m_selectionSquares[0]) // Left { while (pos.x - m_draggingPos.x >= MOVE_STEP) { @@ -1214,15 +1236,19 @@ void Form::onDrag(tgui::Vector2i mousePos) } else // Corner { - const float ratio = selectedWidget->getSize().y / selectedWidget->getSize().x; + float ratio; + if ((selectedWidget->getSize().x != 0) && (selectedWidget->getSize().y != 0)) + ratio = selectedWidget->getSize().y / selectedWidget->getSize().x; + else + ratio = 1; tgui::Vector2f change; if (ratio <= 1) - change = tgui::Vector2f(MOVE_STEP, MOVE_STEP * ratio); + change = tgui::Vector2f(MOVE_STEP, std::max(MOVE_STEP * ratio, 1.f)); else - change = tgui::Vector2f(MOVE_STEP / ratio, MOVE_STEP); + change = tgui::Vector2f(std::max(MOVE_STEP / ratio, 1.f), MOVE_STEP); - if (m_draggingSelectionSquare == m_selectionSquares[0]) // Top left + if (m_draggingSelectionSquare == m_selectionSquares[4]) // Top left { while ((pos.x - m_draggingPos.x >= change.x) && (pos.y - m_draggingPos.y >= change.y)) { @@ -1242,7 +1268,7 @@ void Form::onDrag(tgui::Vector2i mousePos) updated = true; } } - else if (m_draggingSelectionSquare == m_selectionSquares[2]) // Top right + else if (m_draggingSelectionSquare == m_selectionSquares[6]) // Top right { while ((m_draggingPos.x - pos.x >= change.x) && (pos.y - m_draggingPos.y >= change.y)) { @@ -1262,7 +1288,7 @@ void Form::onDrag(tgui::Vector2i mousePos) updated = true; } } - else if (m_draggingSelectionSquare == m_selectionSquares[4]) // Bottom right + else if (m_draggingSelectionSquare == m_selectionSquares[7]) // Bottom right { while ((m_draggingPos.x - pos.x >= change.x) && (m_draggingPos.y - pos.y >= change.y)) { @@ -1280,7 +1306,7 @@ void Form::onDrag(tgui::Vector2i mousePos) updated = true; } } - else if (m_draggingSelectionSquare == m_selectionSquares[6]) // Bottom left + else if (m_draggingSelectionSquare == m_selectionSquares[5]) // Bottom left { while ((pos.x - m_draggingPos.x >= change.x) && (m_draggingPos.y - pos.y >= change.y)) { From 4b49f51668c61d29af1eb6b5e6a735211046b4a2 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 10:59:33 +0100 Subject: [PATCH 18/87] Use SFML 3 for the nightly builds --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b178a211..b618f9592 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1127,8 +1127,8 @@ jobs: needs: [linux, linux-latest-dev, linux-oldest, linux-per-backend, windows, windows-oldest, windows-clang, windows-static-mt, macos, android-sdl, android-sfml-graphics, ios-sfml-graphics, ios-sdl] runs-on: windows-2019 env: - SFML_VERSION: 2.6.2 - MSVC_TOOLSET_VERSION: 141 # VS2017 + SFML_VERSION: 3.0.0 + MSVC_TOOLSET_VERSION: 142 # VS2019 steps: - name: Checkout TGUI uses: actions/checkout@v4 @@ -1139,11 +1139,11 @@ jobs: run: | Install-ChocoPackage doxygen.install mkdir x86 - C:\msys64\usr\bin\wget.exe -nv https://github.com/SFML/SFML/releases/download/${env:SFML_VERSION}/SFML-${env:SFML_VERSION}-windows-vc15-32-bit.zip - 7z x SFML-${env:SFML_VERSION}-windows-vc15-32-bit.zip -o"x86" + C:\msys64\usr\bin\wget.exe -nv https://www.sfml-dev.org/files/SFML-${env:SFML_VERSION}-windows-vc16-32-bit.zip + 7z x SFML-${env:SFML_VERSION}-windows-vc16-32-bit.zip -o"x86" mkdir x64 - C:\msys64\usr\bin\wget.exe -nv https://github.com/SFML/SFML/releases/download/${env:SFML_VERSION}/SFML-${env:SFML_VERSION}-windows-vc15-64-bit.zip - 7z x SFML-${env:SFML_VERSION}-windows-vc15-64-bit.zip -o"x64" + C:\msys64\usr\bin\wget.exe -nv https://www.sfml-dev.org/files/SFML-${env:SFML_VERSION}-windows-vc16-64-bit.zip + 7z x SFML-${env:SFML_VERSION}-windows-vc16-64-bit.zip -o"x64" - name: Remove .git folder run: From 9598e60e33d0bca27a50c6bdc3ae8606cff96d58 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 11:06:53 +0100 Subject: [PATCH 19/87] Removed temporary patches in CI script that should no longer be needed --- .github/workflows/ci.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b618f9592..cfef8cb40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -895,7 +895,7 @@ jobs: android-sdl: runs-on: ubuntu-latest env: - SDL_VERSION: 2.30.7 # Not released yet, so code below downloads latest version and ignores this for now + SDL_VERSION: 2.30.10 SDL_TTF_VERSION: 2.22.0 steps: - name: Checkout TGUI @@ -903,12 +903,11 @@ jobs: with: path: TGUI - # TODO (once SDL 2.30.7 is released: wget -nv -O- "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$SDL_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL2 - name: Download SDL run: | mkdir SDL2 mkdir SDL2_ttf - wget -nv -O- "https://github.com/libsdl-org/SDL/archive/refs/heads/release-2.30.x.tar.gz" | tar --strip-components=1 -xz -C SDL2 + wget -nv -O- "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$SDL_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL2 wget -nv -O- "https://github.com/libsdl-org/SDL_ttf/releases/download/release-$SDL_TTF_VERSION/SDL2_ttf-$SDL_TTF_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL2_ttf - name: Build SDL_RENDERER project @@ -995,7 +994,7 @@ jobs: ios-sfml-graphics: runs-on: macos-15 env: - SFML_VERSION: 2.6.x # At least 2.6.2 is required + SFML_VERSION: 2.6.2 steps: - name: Checkout TGUI uses: actions/checkout@v4 @@ -1010,7 +1009,7 @@ jobs: - name: Build SFML if: steps.cache-sfml.outputs.cache-hit != 'true' run: | - wget -nv https://github.com/SFML/SFML/archive/refs/heads/${SFML_VERSION}.zip + wget -nv https://github.com/SFML/SFML/archive/refs/tags/${SFML_VERSION}.zip unzip ${SFML_VERSION}.zip cmake -GXcode -DCMAKE_INSTALL_PREFIX=SFML_INSTALL -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DBUILD_SHARED_LIBS=OFF -DSFML_BUILD_AUDIO=OFF -DSFML_BUILD_NETWORK=OFF -S SFML-$SFML_VERSION -B SFML-build cmake --build SFML-build --config Debug --target install -- CODE_SIGNING_ALLOWED=NO From f46dbfdfcc31f0a9ca6bceb795872c092e77d684 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 14:14:37 +0100 Subject: [PATCH 20/87] Fixed warnings in CI related to copying freetype dll on Windows --- CMakeLists.txt | 2 +- cmake/Macros.cmake | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe94a0625..022ac432c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ # If the cmake version is higher than the minimum version then enable all new policies, up to the maximum version specified. # When cmake is newer than the highest version then its newest policies will still be set to the old behavior for compatibility. -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.16...3.31) # Include macros such as tgui_set_option include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Macros.cmake) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index b08880dce..0cefd5005 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -129,8 +129,16 @@ function(copy_dlls_to_exe post_build_destination install_destination target) list(APPEND files_to_copy "$") endif() - # Copy the FreeType dll if needed and when we know where it is + # Copy the FreeType dll if needed and if we know where it is if(TGUI_HAS_FONT_BACKEND_FREETYPE AND FREETYPE_WINDOWS_BINARIES_PATH AND NOT TGUI_USE_STATIC_STD_LIBS) + # Turn backslashes into slashes on Windows, because the install() command can fail if the + # FREETYPE_WINDOWS_BINARIES_PATH variable was initialized with an environment variable that contains backslashes. + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.20) + cmake_path(SET FREETYPE_WINDOWS_BINARIES_PATH "${FREETYPE_WINDOWS_BINARIES_PATH}") + else() + file(TO_CMAKE_PATH "${FREETYPE_WINDOWS_BINARIES_PATH}" FREETYPE_WINDOWS_BINARIES_PATH) + endif() + if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(freetype_dll "${FREETYPE_WINDOWS_BINARIES_PATH}/release dll/win64/freetype.dll") else() From 6d76a435fb649e0dc597c320a29d7f00f2525f32 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 22 Dec 2024 14:30:33 +0100 Subject: [PATCH 21/87] Updated version to 1.7 --- CMakeLists.txt | 2 +- changelog.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 022ac432c..effb1beeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Macros.cmake) tgui_set_option(CMAKE_BUILD_TYPE Release STRING "Choose the type of build (Debug or Release)") # Project name and version -project(TGUI VERSION 1.6.1 LANGUAGES CXX) +project(TGUI VERSION 1.7.0 LANGUAGES CXX) # Use the paths from the cmake GNUInstallDirs module as defaults (https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) include(GNUInstallDirs) diff --git a/changelog.md b/changelog.md index 25b258f9f..c3e32c90a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,5 @@ -TGUI 1.7 (TBD) ---------------- +TGUI 1.7 (22 December 2024) +---------------------------- - New widgets: GrowHorizontalLayout and GrowVerticalLayout - Fixed some issues with font scale in SFML font backend From 52a847d3c6b93a3a2a03db557c5f4433312296b1 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sat, 28 Dec 2024 22:29:48 +0100 Subject: [PATCH 22/87] TGUI_RENDERER_PROPERTY_RENDERER define couldn't be used outside of tgui namespace --- include/TGUI/RendererDefines.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/TGUI/RendererDefines.hpp b/include/TGUI/RendererDefines.hpp index 3191da0b9..374bdf668 100644 --- a/include/TGUI/RendererDefines.hpp +++ b/include/TGUI/RendererDefines.hpp @@ -152,7 +152,7 @@ if (renderer) \ setProperty(tgui::String(#NAME), {std::move(renderer)}); \ else \ - setProperty(tgui::String(#NAME), {RendererData::create()}); \ + setProperty(tgui::String(#NAME), {tgui::RendererData::create()}); \ } #define TGUI_RENDERER_PROPERTY_RENDERER(CLASS, NAME, RENDERER) \ From 8b2b539a949896169ba98e7195085c8000f7bc83 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sat, 28 Dec 2024 22:48:35 +0100 Subject: [PATCH 23/87] TTF_GetFontStyle now returns TTF_FontStyleFlags instead of int in SDL_ttf 3 --- src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp index 3e22c593c..97ae87ad4 100644 --- a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp +++ b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp @@ -413,7 +413,11 @@ namespace tgui return {0, 0}; // Temporarily set the underline style +#if TGUI_USE_SDL3 + const TTF_FontStyleFlags oldFontStyle = TTF_GetFontStyle(font); +#else const int oldFontStyle = TTF_GetFontStyle(font); +#endif TTF_SetFontStyle(font, TTF_STYLE_UNDERLINE); int offset = 0; From 602940e2b9d3f2645bb1a8cc2a615e667b7393dd Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Tue, 7 Jan 2025 19:10:53 +0100 Subject: [PATCH 24/87] Added new ContextMenu widget --- changelog.md | 6 + include/TGUI/AllWidgets.hpp | 1 + include/TGUI/Renderers/CheckBoxRenderer.hpp | 3 + .../TGUI/Renderers/ContextMenuRenderer.hpp | 48 + include/TGUI/Renderers/MenuBarRenderer.hpp | 168 +-- .../TGUI/Renderers/MenuWidgetBaseRenderer.hpp | 209 ++++ include/TGUI/Widgets/ContextMenu.hpp | 453 +++++++ include/TGUI/Widgets/MenuBar.hpp | 267 +---- include/TGUI/Widgets/MenuWidgetBase.hpp | 396 ++++++ src/CMakeLists.txt | 7 + src/Loading/Theme.cpp | 15 + src/Loading/WidgetFactory.cpp | 1 + src/Renderers/MenuBarRenderer.cpp | 16 +- src/Renderers/MenuWidgetBaseRenderer.cpp | 48 + src/Widgets/ContextMenu.cpp | 515 ++++++++ src/Widgets/MenuBar.cpp | 1056 +--------------- src/Widgets/MenuWidgetBase.cpp | 1057 +++++++++++++++++ tests/CMakeLists.txt | 1 + tests/Widgets/ContextMenu.cpp | 448 +++++++ tests/expected/ContextMenu.png | Bin 0 -> 2889 bytes tests/expected/ContextMenu_Closed.png | Bin 0 -> 645 bytes tests/expected/ContextMenu_HoverDisabled.png | Bin 0 -> 2889 bytes .../ContextMenu_HoverDisabled_Textured.png | Bin 0 -> 4199 bytes .../expected/ContextMenu_SubMenuItemHover.png | Bin 0 -> 4146 bytes .../ContextMenu_SubMenuItemHover_Textured.png | Bin 0 -> 6344 bytes tests/expected/ContextMenu_SubMenuOpen.png | Bin 0 -> 4154 bytes .../ContextMenu_SubMenuOpen_Textured.png | Bin 0 -> 6346 bytes tests/expected/ContextMenu_Textured.png | Bin 0 -> 4199 bytes themes/BabyBlue.txt | 4 + themes/Black.txt | 6 + themes/development/Black/Black.txt.in | 6 + 31 files changed, 3313 insertions(+), 1418 deletions(-) create mode 100644 include/TGUI/Renderers/ContextMenuRenderer.hpp create mode 100644 include/TGUI/Renderers/MenuWidgetBaseRenderer.hpp create mode 100644 include/TGUI/Widgets/ContextMenu.hpp create mode 100644 include/TGUI/Widgets/MenuWidgetBase.hpp create mode 100644 src/Renderers/MenuWidgetBaseRenderer.cpp create mode 100644 src/Widgets/ContextMenu.cpp create mode 100644 src/Widgets/MenuWidgetBase.cpp create mode 100644 tests/Widgets/ContextMenu.cpp create mode 100644 tests/expected/ContextMenu.png create mode 100644 tests/expected/ContextMenu_Closed.png create mode 100644 tests/expected/ContextMenu_HoverDisabled.png create mode 100644 tests/expected/ContextMenu_HoverDisabled_Textured.png create mode 100644 tests/expected/ContextMenu_SubMenuItemHover.png create mode 100644 tests/expected/ContextMenu_SubMenuItemHover_Textured.png create mode 100644 tests/expected/ContextMenu_SubMenuOpen.png create mode 100644 tests/expected/ContextMenu_SubMenuOpen_Textured.png create mode 100644 tests/expected/ContextMenu_Textured.png diff --git a/changelog.md b/changelog.md index c3e32c90a..b3cebaaf8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +TGUI 1.8 (TBD) +--------------- + +- New widget: ContextMenu + + TGUI 1.7 (22 December 2024) ---------------------------- diff --git a/include/TGUI/AllWidgets.hpp b/include/TGUI/AllWidgets.hpp index d5d25b27e..518755abc 100644 --- a/include/TGUI/AllWidgets.hpp +++ b/include/TGUI/AllWidgets.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/include/TGUI/Renderers/CheckBoxRenderer.hpp b/include/TGUI/Renderers/CheckBoxRenderer.hpp index f9b2fe849..e631d103f 100644 --- a/include/TGUI/Renderers/CheckBoxRenderer.hpp +++ b/include/TGUI/Renderers/CheckBoxRenderer.hpp @@ -31,6 +31,9 @@ TGUI_MODULE_EXPORT namespace tgui { + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Renderer for the CheckBox widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class TGUI_API CheckBoxRenderer : public RadioButtonRenderer { public: diff --git a/include/TGUI/Renderers/ContextMenuRenderer.hpp b/include/TGUI/Renderers/ContextMenuRenderer.hpp new file mode 100644 index 000000000..c20d672f9 --- /dev/null +++ b/include/TGUI/Renderers/ContextMenuRenderer.hpp @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_CONTEXT_MENU_RENDERER_HPP +#define TGUI_CONTEXT_MENU_RENDERER_HPP + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Renderer for the ContextMenu widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API ContextMenuRenderer : public MenuWidgetBaseRenderer + { + public: + using MenuWidgetBaseRenderer::MenuWidgetBaseRenderer; + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_CONTEXT_MENU_RENDERER_HPP diff --git a/include/TGUI/Renderers/MenuBarRenderer.hpp b/include/TGUI/Renderers/MenuBarRenderer.hpp index 8659e03ad..e18bc656a 100644 --- a/include/TGUI/Renderers/MenuBarRenderer.hpp +++ b/include/TGUI/Renderers/MenuBarRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -25,7 +25,7 @@ #ifndef TGUI_MENU_BAR_RENDERER_HPP #define TGUI_MENU_BAR_RENDERER_HPP -#include +#include ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -34,91 +34,11 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Renderer for the MenuBar widget ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - class TGUI_API MenuBarRenderer : public WidgetRenderer + class TGUI_API MenuBarRenderer : public MenuWidgetBaseRenderer { public: - using WidgetRenderer::WidgetRenderer; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the background color of the menu bar - /// - /// @param backgroundColor The new background color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setBackgroundColor(Color backgroundColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the background color - /// - /// @return Background color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getBackgroundColor() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the background color of the selected item - /// - /// @param backgroundColor The new selected item background color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSelectedBackgroundColor(Color backgroundColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the background color of the selected item - /// - /// @return Selected item background color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getSelectedBackgroundColor() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the color of the text - /// - /// @param textColor The new text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setTextColor(Color textColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the color of the text - /// - /// @return Text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getTextColor() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the color of the text from the selected item - /// - /// @param textColor The new selected text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSelectedTextColor(Color textColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the color of the text from the selected item - /// - /// @return Selected text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getSelectedTextColor() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the color of the text when disabled - /// @param textColor The new text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setTextColorDisabled(Color textColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the color of the text when disabled - /// @return Text color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getTextColorDisabled() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the color of the separators - /// @param separatorColor The new separator color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSeparatorColor(Color separatorColor); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the color of the separators - /// @return Separator color - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Color getSeparatorColor() const; + using MenuWidgetBaseRenderer::MenuWidgetBaseRenderer; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Changes the image that is used to fill the entire menu bar @@ -135,86 +55,6 @@ TGUI_MODULE_EXPORT namespace tgui /// @return Background texture ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD const Texture& getTextureBackground() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the image that is displayed when the menu item is not selected - /// - /// @param texture New item background texture - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setTextureItemBackground(const Texture& texture); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the image that is displayed when the menu item is not selected - /// - /// @return Item background texture - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD const Texture& getTextureItemBackground() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the image that is used as background of the selected menu item - /// - /// @param texture New selected item background texture - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setTextureSelectedItemBackground(const Texture& texture); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the image that is used as background of the selected menu item - /// - /// @return Selected item background texture - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD const Texture& getTextureSelectedItemBackground() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the distance between the text and the side of the menu item - /// - /// @param distanceToSide distance between the text and the side of the menu item - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setDistanceToSide(float distanceToSide); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the distance between the text and the side of the menu item - /// - /// @return Distance between the text and the side of the menu item - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD float getDistanceToSide() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the height of the separators - /// @param thickness The new separator thickness - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSeparatorThickness(float thickness); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the height of the separators - /// @return Separator thickness - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD float getSeparatorThickness() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the distance between the separator and the menu items above and below it - /// @param padding Padding above and below the separator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSeparatorVerticalPadding(float padding); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the distance between the separator and the menu items above and below it - /// @return Padding above and below the separator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD float getSeparatorVerticalPadding() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Changes the distance between the separator and the sides of the menu - /// @param padding Padding next to the separator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setSeparatorSidePadding(float padding); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the distance between the separator and the sides of the menu - /// @return Padding next to the separator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD float getSeparatorSidePadding() const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/TGUI/Renderers/MenuWidgetBaseRenderer.hpp b/include/TGUI/Renderers/MenuWidgetBaseRenderer.hpp new file mode 100644 index 000000000..85ba62a18 --- /dev/null +++ b/include/TGUI/Renderers/MenuWidgetBaseRenderer.hpp @@ -0,0 +1,209 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_MENU_WIDGET_BASE_RENDERER_HPP +#define TGUI_MENU_WIDGET_BASE_RENDERER_HPP + +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Renderer for the MenuBar widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API MenuWidgetBaseRenderer : public WidgetRenderer + { + public: + + using WidgetRenderer::WidgetRenderer; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the background color + /// + /// @param backgroundColor The new background color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setBackgroundColor(Color backgroundColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the background color + /// + /// @return Background color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getBackgroundColor() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the background color of the selected item + /// + /// @param backgroundColor The new selected item background color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSelectedBackgroundColor(Color backgroundColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the background color of the selected item + /// + /// @return Selected item background color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getSelectedBackgroundColor() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the color of the text + /// + /// @param textColor The new text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setTextColor(Color textColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the color of the text + /// + /// @return Text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getTextColor() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the color of the text from the selected item + /// + /// @param textColor The new selected text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSelectedTextColor(Color textColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the color of the text from the selected item + /// + /// @return Selected text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getSelectedTextColor() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the color of the text when disabled + /// @param textColor The new text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setTextColorDisabled(Color textColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the color of the text when disabled + /// @return Text color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getTextColorDisabled() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the color of the separators + /// @param separatorColor The new separator color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSeparatorColor(Color separatorColor); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the color of the separators + /// @return Separator color + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Color getSeparatorColor() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the image that is displayed when the menu item is not selected + /// + /// @param texture New item background texture + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setTextureItemBackground(const Texture& texture); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the image that is displayed when the menu item is not selected + /// + /// @return Item background texture + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD const Texture& getTextureItemBackground() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the image that is used as background of the selected menu item + /// + /// @param texture New selected item background texture + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setTextureSelectedItemBackground(const Texture& texture); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the image that is used as background of the selected menu item + /// + /// @return Selected item background texture + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD const Texture& getTextureSelectedItemBackground() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the distance between the text and the side of the menu item + /// + /// @param distanceToSide distance between the text and the side of the menu item + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setDistanceToSide(float distanceToSide); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the distance between the text and the side of the menu item + /// + /// @return Distance between the text and the side of the menu item + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getDistanceToSide() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the height of the separators + /// @param thickness The new separator thickness + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSeparatorThickness(float thickness); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the height of the separators + /// @return Separator thickness + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getSeparatorThickness() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the distance between the separator and the menu items above and below it + /// @param padding Padding above and below the separator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSeparatorVerticalPadding(float padding); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the distance between the separator and the menu items above and below it + /// @return Padding above and below the separator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getSeparatorVerticalPadding() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the distance between the separator and the sides of the menu + /// @param padding Padding next to the separator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSeparatorSidePadding(float padding); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the distance between the separator and the sides of the menu + /// @return Padding next to the separator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getSeparatorSidePadding() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_MENU_WIDGET_BASE_RENDERER_HPP diff --git a/include/TGUI/Widgets/ContextMenu.hpp b/include/TGUI/Widgets/ContextMenu.hpp new file mode 100644 index 000000000..734be7160 --- /dev/null +++ b/include/TGUI/Widgets/ContextMenu.hpp @@ -0,0 +1,453 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_CONTEXT_MENU_HPP +#define TGUI_CONTEXT_MENU_HPP + +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Context menu widget + /// + /// @since TGUI 1.8 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API ContextMenu : public MenuWidgetBase + { + public: + + using Ptr = std::shared_ptr; //!< Shared widget pointer + using ConstPtr = std::shared_ptr; //!< Shared constant widget pointer + + static constexpr const char StaticWidgetType[] = "ContextMenu"; //!< Type name of the widget + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Constructor + /// @param typeName Type of the widget + /// @param initRenderer Should the renderer be initialized? Should be true unless a derived class initializes it. + /// @see create + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ContextMenu(const char* typeName = StaticWidgetType, bool initRenderer = true); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Creates a new menu bar widget + /// + /// @return The new menu bar + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static ContextMenu::Ptr create(); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Makes a copy of another menu bar + /// + /// @param menuBar The other menu bar + /// + /// @return The new menu bar + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD static ContextMenu::Ptr copy(const ContextMenu::ConstPtr& menuBar); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed + /// @return Temporary pointer to the renderer that may be shared with other widgets using the same renderer + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD ContextMenuRenderer* getSharedRenderer() override; + TGUI_NODISCARD const ContextMenuRenderer* getSharedRenderer() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed + /// @return Temporary pointer to the renderer + /// @warning After calling this function, the widget has its own copy of the renderer and it will no longer be shared. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD ContextMenuRenderer* getRenderer() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns whether the context menu is open + /// + /// The context menu will render nothing until it is opened. + /// @see openMenu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool isMenuOpen() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Opens the context menu at the position of this widget + /// + /// The context menu will render nothing until this function is called. + /// Once the user clicked an item in the menu, the menu will be closed and you need to call this function again in order + /// for the menu to become visible again. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void openMenu(); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Opens the context menu at a certain position + /// + /// The context menu will render nothing until this function is called. + /// Once the user clicked an item in the menu, the menu will be closed and you need to call this function again in order + /// for the menu to become visible again. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void openMenu(Vector2f position); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Closes the context menu if it was open + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void closeMenu() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the height of the items in the context menu + /// + /// @param itemHeight The size of a single item in the context menu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setItemHeight(float itemHeight); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the height of the items in the context menu + /// + /// @return The item height + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getItemHeight() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Connects a signal handler to the "MenuItemClicked" callback that will only be called when a specific + /// menu item was clicked. + /// + /// @param menuItem Menu item which should trigger the signal (assuming there are no submenus) + /// @param handler Callback function to call + /// @param args Optional extra arguments to pass to the signal handler when the signal is emitted + /// + /// @return Unique id of the connection + /// + /// The hierarchy does not need to exist yet and the signal will still exist when removing and readding the menu items. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + template + unsigned int connectMenuItem(const String& menuItem, Func&& handler, const Args&... args) + { + return connectMenuItem(std::vector{menuItem}, std::forward(handler), args...); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Connects a signal handler to the "MenuItemClicked" callback that will only be called when a specific + /// menu item was clicked. + /// + /// @param hierarchy Hierarchy of the menu items, ending with menu item that should trigger the signal when pressed + /// @param handler Callback function to call + /// @param args Optional extra arguments to pass to the signal handler when the signal is emitted + /// + /// @return Unique id of the connection + /// + /// The hierarchy does not need to exist yet and the signal will still exist when removing and readding the menu items. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + template + unsigned int connectMenuItem(const std::vector& hierarchy, Func&& handler, const Args&... args) + { +#if defined(__cpp_lib_invoke) && (__cpp_lib_invoke >= 201411L) + return onMenuItemClick.connect( + [=](const std::vector& clickedMenuItem) + { + if (clickedMenuItem == hierarchy) + std::invoke(handler, args...); + } + ); +#else + return onMenuItemClick.connect( + [f=std::function(handler),args...,hierarchy](const std::vector& clickedMenuItem) + { + if (clickedMenuItem == hierarchy) + f(args...); + } + ); +#endif + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief This function is overriden to do nothing + /// + /// @param size This parameter is ignored by this overriden function + /// + /// @warning The size of the ContextMenu can't be manually set! It depends on the items and the MinimumMenuWidth property. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSize(const Layout2d& size) override; + using Widget::setSize; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Enables or disables the widget + /// @param enabled Is the widget enabled? + /// + /// The disabled widget will no longer receive events and thus no longer send callbacks. + /// All widgets are enabled by default. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setEnabled(bool enabled) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Adds a new menu item to the menu + /// + /// @param text The text written on this menu item + /// + /// @code + /// contextMenu->addMenuItem("Cut"); + /// contextMenu->addMenuItem("Copy"); + /// contextMenu->addMenuItem("Paste"); + /// @endcode + /// + /// If the "-" string is given as menu item then a separator will appear instead of an item. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void addMenuItem(const String& text); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Adds a new sub menu item + /// + /// @param hierarchy Hierarchy of the menu items, ending with menu item to be added + /// @param createParents Should the hierarchy be created if it did not exist yet? + /// + /// @return True when the item was added, false when createParents was false and the parents hierarchy does not exist + /// or if hierarchy is empty. + /// + /// @code + /// contextMenu->addMenuItem({"Edit", "Undo"}); + /// contextMenu->addMenuItem({"Edit", "Redo"}); + /// @endcode + /// + /// If the "-" string is given as menu item then a separator will appear instead of an item. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool addMenuItem(const std::vector& hierarchy, bool createParents = true); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the text of an existing menu item + /// + /// @param hierarchy Hierarchy of the menu items, ending with the menu item that is to be renamed + /// @param text The new text written on this menu item + /// + /// @return True when the menu item was renamed, false when the menu item was not found + /// + /// @code + /// contextMenu->addMenuItem({"Edit", "Undo"}); + /// contextMenu->changeMenuItem({"Edit", "Undo"}, "Undo action"); + /// @endcode + /// + /// This function can also be used to rename items without submenus, by passing a hierarchy with only one element. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool changeMenuItem(const std::vector& hierarchy, const String& text); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes all menu items + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void removeAllMenuItems(); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes a menu item + /// + /// @param menuItem The name of the menu item to remove + /// + /// @return True when the item was removed, false when menuItem was not found + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool removeMenuItem(const String& menuItem); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes a sub menu item + /// + /// @param hierarchy Hierarchy of the menu item, ending with menu item to be deleted + /// @param removeParentsWhenEmpty Also delete the parent of the deleted menu item if it has no other children + /// + /// @return True when the menu item existed and was removed, false when hierarchy was incorrect + /// + /// @code + /// contextMenu->removeMenuItem({"Edit", "Undo"}); + /// @endcode + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool removeMenuItem(const std::vector& hierarchy, bool removeParentsWhenEmpty = true); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Removes a all menu items below a (sub) menu + /// + /// @param hierarchy Hierarchy of the menu item, ending with the sub menu containing the items + /// + /// @return True when the menu item existed and its children were removed, false when hierarchy was incorrect + /// + /// @code + /// contextMenu->removeSubMenuItems({"File", "Recent files"}); + /// @endcode + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool removeSubMenuItems(const std::vector& hierarchy); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Enable or disable a menu item + /// @param menuItem The name of the menu item to enable or disable + /// @param enabled Should the menu item be enabled or disabled? + /// @return True when the menu item exists, false when menuItem was not found + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool setMenuItemEnabled(const String& menuItem, bool enabled); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Enable or disable a menu item + /// @param hierarchy Hierarchy of menu items, ending with the menu item to enable/disable + /// @param enabled Should the menu item be enabled or disabled? + /// @return True when the menu item exists, false when hierarchy was incorrect + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool setMenuItemEnabled(const std::vector& hierarchy, bool enabled); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Check if a menu item is enabled or disabled + /// @param menuItem The name of the menu item to check + /// @return True if the menu item is enabled, false if it was disabled or when the menuItem did not exist + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool getMenuItemEnabled(const String& menuItem) const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Check if a menu item is enabled or disabled + /// @param hierarchy Hierarchy of menu items, ending with the menu item to check + /// @return True if the menu item is enabled, false if it was disabled or when the hierarchy was incorrect + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool getMenuItemEnabled(const std::vector& hierarchy) const; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the minimum width of the menus + /// + /// When a menu is displayed, the width will be either this or the width of the longest text in the menu. + /// + /// @param minimumWidth minimum width of the menus + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setMinimumMenuWidth(float minimumWidth); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the minimum width of the menus + /// + /// @return minimum width of the menus + /// + /// @see setMinimumMenuWidth + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getMinimumMenuWidth() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the menu items, including submenus + /// @return List of menu items + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD std::vector getMenuItems() const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget + /// + /// @return Is the mouse on top of the widget? + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool isMouseOnWidget(Vector2f pos) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Draw the widget to a render target + /// + /// @param target Render target to draw to + /// @param states Current render states + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void draw(BackendRenderTarget& target, RenderStates states) const override; + + protected: + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Function called when one of the properties of the renderer is changed + /// + /// @param property Name of the property that was changed + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void rendererChanged(const String& property) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Saves the widget as a tree node in order to save it to a file + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD std::unique_ptr save(SavingRenderersMap& renderers) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Loads the widget from a tree of nodes + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void load(const std::unique_ptr& node, const LoadingRenderersMap& renderers) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Called when the text size is changed (either by setTextSize or via the renderer) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void updateTextSize() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Makes a copy of the widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Widget::Ptr clone() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Triggers the onMenuItemClick callback + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void emitMenuItemClick(const std::vector& hierarchy) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Returns the height of a normal menu item (i.e. not a separator). For a context menu this is the ItemHeight. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD float getDefaultMenuItemHeight() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Left mouse button was released while the menu might be open + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void leftMouseReleasedOnMenu() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Is the mouse located on the opened menu? + /// @param pos Mouse position + /// @return True if mouse on menu, false otherwise. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool isMouseOnOpenMenu(Vector2f pos) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Mouse moved on top of the menu + /// @param pos Mouse position + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void mouseMovedOnMenu(Vector2f pos) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Deselects the selected item of the deepest open submenu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void deselectDeepestItem() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Called from OpenMenuPlaceholder to draw the menu that is currently open + /// @param target Render target to draw to + /// @param states Current render states + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void drawOpenMenu(BackendRenderTarget& target, RenderStates states) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + Menu m_menu; + bool m_menuOpen = false; + float m_itemHeight = 0; + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_CONTEXT_MENU_HPP diff --git a/include/TGUI/Widgets/MenuBar.hpp b/include/TGUI/Widgets/MenuBar.hpp index 8e25f021d..05e876d02 100644 --- a/include/TGUI/Widgets/MenuBar.hpp +++ b/include/TGUI/Widgets/MenuBar.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -25,20 +25,17 @@ #ifndef TGUI_MENU_BAR_HPP #define TGUI_MENU_BAR_HPP -#include +#include #include -#include ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_MODULE_EXPORT namespace tgui { - class MenuBarMenuPlaceholder; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Menu bar widget ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - class TGUI_API MenuBar : public Widget + class TGUI_API MenuBar : public MenuWidgetBase { public: @@ -47,23 +44,6 @@ TGUI_MODULE_EXPORT namespace tgui static constexpr const char StaticWidgetType[] = "MenuBar"; //!< Type name of the widget - /// @brief Used for return value of getMenus - struct GetMenusElement - { - String text; - bool enabled; - std::vector menuItems; - }; - - /// @internal - struct Menu - { - Text text; - bool enabled = true; - int selectedMenuItem = -1; - std::vector menuItems; - }; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal /// @brief Constructor @@ -73,26 +53,6 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MenuBar(const char* typeName = StaticWidgetType, bool initRenderer = true); - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Copy constructor - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar(const MenuBar& other); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Move constructor - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar(MenuBar&& other) noexcept; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Copy assignment operator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar& operator=(const MenuBar& other); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Move assignment operator - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar& operator=(MenuBar&& other) noexcept; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Creates a new menu bar widget /// @@ -392,14 +352,13 @@ TGUI_MODULE_EXPORT namespace tgui /// @brief Changes the minimum width of the submenus /// /// When a submenu is displayed, the width will be either this or the width of the longest text in the submenu. - /// The default minimum width is 125 pixels. /// /// @param minimumWidth minimum width of the submenus ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setMinimumSubMenuWidth(float minimumWidth); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the distance between the text and the side of the menu item + /// @brief Returns the minimum width of the submenus /// /// @return minimum width of the submenus /// @@ -430,7 +389,7 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Closes the open menu when one of the menus is open ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void closeMenu(); + void closeMenu() override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget @@ -465,17 +424,6 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Retrieves a signal based on its name - /// - /// @param signalName Name of the signal - /// - /// @return Signal that corresponds to the name - /// - /// @throw Exception when the name does not match any signal - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Signal& getSignal(String signalName) override; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Function called when one of the properties of the renderer is changed /// @@ -509,79 +457,29 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void openMenu(std::size_t menuIndex); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - /// Helper function to create a new menu or menu item - void createMenu(std::vector& menus, const String& text); - - /// @internal - /// Recursively search for the menu containing the menu item specified in the hierarchy, creating the hierarchy if requested. - /// The initial call to this function must pass "parentIndex = 0" and "menus = m_menus". - TGUI_NODISCARD Menu* findMenu(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus, bool createParents); - - /// @internal - /// Recursively search for the menu containing the menu item specified in the hierarchy. - /// The initial call to this function must pass "parentIndex = 0" and "menus = m_menus". - TGUI_NODISCARD const Menu* findMenu(const std::vector& hierarchy, unsigned int parentIndex, const std::vector& menus) const; - - /// @internal - /// Search for the menu item specified in the hierarchy and return a pointer to it. - TGUI_NODISCARD Menu* findMenuItem(const std::vector& hierarchy); - - /// @internal - /// Search for the menu item specified in the hierarchy and return a read-only pointer to it. - TGUI_NODISCARD const Menu* findMenuItem(const std::vector& hierarchy) const; - - /// @internal - /// Helper function to load the menus when the menu bar is being loaded from a text file - void loadMenus(const std::unique_ptr& node, std::vector& menus); - - /// @internal - /// Closes the open menu and its submenus - void closeSubMenus(std::vector& menus, int& selectedMenu); - - /// @internal - void deselectBottomItem(); - - /// @internal - void updateMenuTextColor(Menu& menu, bool selected); - - /// @internal - void updateTextColors(std::vector& menus, int selectedMenu); - - /// @internal - void updateTextOpacity(std::vector& menus); - - /// @internal - void updateTextFont(std::vector& menus); - - /// @internal - /// Calculate the width that is needed for the menu to fit all menu items - TGUI_NODISCARD float calculateMenuWidth(const Menu& menu) const; - - /// @internal - /// Returns the height of the menu item or the separator - TGUI_NODISCARD float getMenuItemHeight(const Menu& menuItem) const; - - /// @internal - /// Calculates the height of all menu items and separators in a menu - TGUI_NODISCARD float calculateOpenMenuHeight(const std::vector& menuItems) const; - - /// @internal - TGUI_NODISCARD Vector2f calculateSubmenuOffset(const Menu& menu, float globalLeftPos, float menuWidth, float subMenuWidth, bool& openSubMenuToRight) const; - - /// @internal - TGUI_NODISCARD bool isMouseOnTopOfMenu(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, const Menu& menu, float menuWidth) const; + /// @brief Draw the backgrounds and text of the menu names on top of the bar itself + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void drawMenusOnBar(BackendRenderTarget& target, RenderStates states) const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - TGUI_NODISCARD bool findMenuItemBelowMouse(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, Menu& menu, float menuWidth, Menu** resultMenu, std::size_t* resultSelectedMenuItem); + /// @brief Calculates the offset of an open menu relative to the menu bar + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f calculateMenuOffset(std::size_t visibleMenuIdx) const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - /// Draw the backgrounds and text of the menu names on top of the bar itself - void drawMenusOnBar(BackendRenderTarget& target, RenderStates states) const; + /// @brief Triggers the onMenuItemClick callback + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void emitMenuItemClick(const std::vector& hierarchy) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - /// Draw an open menu and recusively draw submenus when open - void drawMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, float menuWidth, float globalLeftPos, bool openSubMenuToRight) const; + /// @brief Deselects the selected item of the deepest open submenu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void deselectDeepestItem() override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal @@ -589,140 +487,41 @@ TGUI_MODULE_EXPORT namespace tgui /// @param pos Mouse position /// @return True if mouse on menu, false otherwise. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD bool isMouseOnOpenMenu(Vector2f pos) const; + TGUI_NODISCARD bool isMouseOnOpenMenu(Vector2f pos) const override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - /// @brief Left mouse button was released on top of a menu + /// @brief Returns the height of a normal menu item (i.e. not a separator). For a menu bar this is the height of the bar. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void leftMouseReleasedOnMenu(); + TGUI_NODISCARD float getDefaultMenuItemHeight() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Left mouse button was released while a menu might be open + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void leftMouseReleasedOnMenu() override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal /// @brief Mouse moved on top of a menu /// @param pos Mouse position ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void mouseMovedOnMenu(Vector2f pos); + void mouseMovedOnMenu(Vector2f pos) override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal - /// @brief Called from MenuBarMenuPlaceholder to draw the menu that is currently open + /// @brief Called from OpenMenuPlaceholder to draw the menu that is currently open /// @param target Render target to draw to /// @param states Current render states ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void drawOpenMenu(BackendRenderTarget& target, RenderStates states) const; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public: - - /// One of the menu items was clicked. - /// Optional parameters: - /// - The text of the clicked menu item - /// - List containing both the name of the menu and the menu item that was clicked - SignalItemHierarchy onMenuItemClick = {"MenuItemClicked"}; + void drawOpenMenu(BackendRenderTarget& target, RenderStates states) const override; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: std::vector m_menus; - std::shared_ptr m_menuWidgetPlaceholder; - int m_visibleMenu = -1; - - float m_minimumSubMenuWidth = 125; - - bool m_invertedMenuDirection = false; - Sprite m_spriteBackground; - Sprite m_spriteItemBackground; - Sprite m_spriteSelectedItemBackground; - - // Cached renderer properties - Color m_backgroundColorCached; - Color m_selectedBackgroundColorCached; - Color m_textColorCached; - Color m_selectedTextColorCached; - Color m_textColorDisabledCached; - Color m_separatorColorCached = Color::Black; - float m_separatorThicknessCached = 1; - float m_separatorVerticalPaddingCached = 0; - float m_separatorSidePaddingCached = 0; - float m_distanceToSideCached = 0; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - friend class MenuBarMenuPlaceholder; - }; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Widget that is added to a container when the user clicks on the menu bar. This widget will be added in front of - /// all other widgets to ensure that the menus from the menu bar are always drawn in front of other widgets. - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - class MenuBarMenuPlaceholder : public Widget - { - public: - - // Instances of this class can't be copied - MenuBarMenuPlaceholder(const MenuBarMenuPlaceholder&) = delete; - MenuBarMenuPlaceholder& operator=(const MenuBarMenuPlaceholder&) = delete; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Constructor - /// @param menuBar The menu bar that owns this menu - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBarMenuPlaceholder(MenuBar* menuBar); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the entire size that the widget is using - /// - /// @return Full size of the widget - /// - /// This MenuBarMenuPlaceholder widget will try to fit the entire screen to absorb all mouse events. - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Vector2f getFullSize() const override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns the distance between the position where the widget is drawn and where the widget is placed - /// - /// @return Offset of the widget - /// - /// The offset equals -getPosition() for MenuBarMenuPlaceholder because it tries to fill the entire screen. - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Vector2f getWidgetOffset() const override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of an open menu - /// @return Is the mouse on top of an open menu from the menu bar? - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD bool isMouseOnWidget(Vector2f pos) const override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @brief Draw the widget to a render target - /// - /// @param target Render target to draw to - /// @param states Current render states - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void draw(BackendRenderTarget& target, RenderStates states) const override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @internal - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void leftMouseButtonNoLongerDown() override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// @internal - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void mouseMoved(Vector2f pos) override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Makes a copy of the widget - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TGUI_NODISCARD Widget::Ptr clone() const override; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - private: - MenuBar* m_menuBar; - bool m_mouseWasOnMenuBar = true; // When a menu opens then the mouse will be on top of the menu bar }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/TGUI/Widgets/MenuWidgetBase.hpp b/include/TGUI/Widgets/MenuWidgetBase.hpp new file mode 100644 index 000000000..a96548af5 --- /dev/null +++ b/include/TGUI/Widgets/MenuWidgetBase.hpp @@ -0,0 +1,396 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TGUI_MENU_WIDGET_BASE_HPP +#define TGUI_MENU_WIDGET_BASE_HPP + +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TGUI_MODULE_EXPORT namespace tgui +{ + class OpenMenuPlaceholder; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Base class for MenuBar and ContextMenu + /// + /// @since TGUI 1.8 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class TGUI_API MenuWidgetBase : public Widget + { + public: + + /// @brief Used for return value of getMenus + struct GetMenusElement + { + String text; + bool enabled; + std::vector menuItems; + }; + + public: + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Copy constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MenuWidgetBase(const MenuWidgetBase& other); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Move constructor + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MenuWidgetBase(MenuWidgetBase&& other) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Copy assignment operator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MenuWidgetBase& operator=(const MenuWidgetBase& other); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Move assignment operator + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MenuWidgetBase& operator=(MenuWidgetBase&& other) noexcept; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed + /// @return Temporary pointer to the renderer that may be shared with other widgets using the same renderer + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD MenuWidgetBaseRenderer* getSharedRenderer() override; + TGUI_NODISCARD const MenuWidgetBaseRenderer* getSharedRenderer() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed + /// @return Temporary pointer to the renderer + /// @warning After calling this function, the widget has its own copy of the renderer and it will no longer be shared. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD MenuWidgetBaseRenderer* getRenderer() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Closes the menu if it was open + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void closeMenu() = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + struct Menu + { + Text text; + bool enabled = true; + int selectedMenuItem = -1; + std::vector menuItems; + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Constructor + /// @param typeName Type of the widget + /// @param initRenderer Should the renderer be initialized? Should be true unless a derived class initializes it. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MenuWidgetBase(const char* typeName, bool initRenderer); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Retrieves a signal based on its name + /// + /// @param signalName Name of the signal + /// + /// @return Signal that corresponds to the name + /// + /// @throw Exception when the name does not match any signal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Signal& getSignal(String signalName) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Function called when one of the properties of the renderer is changed + /// + /// @param property Name of the property that was changed + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void rendererChanged(const String& property) override; + + /// @internal + /// Helper function to create a new menu or menu item + void createMenu(std::vector& menus, const String& text); + + /// @internal + /// Recursively search for the menu containing the menu item specified in the hierarchy, creating the hierarchy if requested. + /// The initial call to this function must pass "parentIndex = 0". + TGUI_NODISCARD Menu* findMenuItemParent(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus, bool createParents); + + /// @internal + /// Recursively search for the menu containing the menu item specified in the hierarchy. + /// The initial call to this function must pass "parentIndex = 0". + TGUI_NODISCARD const Menu* findMenuItemParent(const std::vector& hierarchy, unsigned int parentIndex, const std::vector& menus) const; + + /// @internal + /// Search for the menu item specified in the hierarchy and return a pointer to it. + TGUI_NODISCARD Menu* findMenuItem(const std::vector& hierarchy, std::vector& menus); + + /// @internal + /// Search for the menu item specified in the hierarchy and return a read-only pointer to it. + TGUI_NODISCARD const Menu* findMenuItem(const std::vector& hierarchy, const std::vector& menus) const; + + /// @internal + /// Helper function to load the menus when the menu bar is being loaded from a text file + void loadMenus(const std::unique_ptr& node, std::vector& menus); + + /// @internal + /// Closes the open menu and its submenus + void closeSubMenus(std::vector& menus, int& selectedMenu); + + /// @internal + void updateMenuTextColor(Menu& menu, bool selected); + + /// @internal + void updateTextColors(std::vector& menus, int selectedMenu); + + /// @internal + void updateTextOpacity(std::vector& menus); + + /// @internal + void updateTextFont(std::vector& menus); + + /// @internal + /// Calculate the width that is needed for the menu to fit all menu items + TGUI_NODISCARD float calculateMenuWidth(const Menu& menu) const; + + /// @internal + /// Returns the height of the menu item or the separator + TGUI_NODISCARD float getMenuItemHeight(const Menu& menuItem) const; + + /// @internal + /// Calculates the height of all menu items and separators in a menu + TGUI_NODISCARD float calculateOpenMenuHeight(const std::vector& menuItems) const; + + /// @internal + TGUI_NODISCARD Vector2f calculateSubmenuOffset(const Menu& menu, float globalLeftPos, float menuWidth, float subMenuWidth, bool& openSubMenuToRight) const; + + /// @internal + TGUI_NODISCARD bool isMouseOnTopOfMenu(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, const Menu& menu, float menuWidth) const; + + /// @internal + TGUI_NODISCARD bool findMenuItemBelowMouse(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, Menu& menu, float menuWidth, Menu** resultMenu, std::size_t* resultSelectedMenuItem); + + /// @internal + static bool isSeparator(const Menu& menuItem); + + /// @internal + static bool removeMenuImpl(const std::vector& hierarchy, bool removeParentsWhenEmpty, unsigned int parentIndex, std::vector& menus); + + /// @internal + static bool removeSubMenusImpl(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus); + + /// @internal + static void setTextSizeImpl(std::vector& menus, unsigned int textSize); + + /// @internal + static std::vector getMenusImpl(const std::vector& menus); + + /// @internal + static void saveMenus(const std::unique_ptr& parentNode, const std::vector& menus); + + /// @internal + /// Draw an open menu and recusively draw submenus when open + void drawMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, float menuWidth, float globalLeftPos, bool openSubMenuToRight) const; + + /// @internal + void leftMouseReleasedOnMenu(const Menu* menu); + + /// @internal + bool isMouseOnOpenMenu(Vector2f pos, const Menu& menu, Vector2f menuOffset) const; + + /// @internal + void mouseMovedOnMenu(Vector2f pos, Menu& menu, Vector2f menuOffset); + + /// @internal + void deselectDeepestItem(Menu* menu); + + /// @internal + void drawOpenMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, Vector2f menuOffset) const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Triggers the onMenuItemClick callback + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void emitMenuItemClick(const std::vector& hierarchy) = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Returns the height of a normal menu item (i.e. not a separator) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD virtual float getDefaultMenuItemHeight() const = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Left mouse button was released while a menu might be open + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void leftMouseReleasedOnMenu() = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Is the mouse located on one of an open menu? + /// @param pos Mouse position + /// @return True if mouse on menu, false otherwise. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD virtual bool isMouseOnOpenMenu(Vector2f pos) const = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Mouse moved on top of a menu + /// @param pos Mouse position + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void mouseMovedOnMenu(Vector2f pos) = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Deselects the selected item of the deepest open submenu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void deselectDeepestItem() = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + /// @brief Called from OpenMenuPlaceholder to draw the menu that is currently open + /// @param target Render target to draw to + /// @param states Current render states + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual void drawOpenMenu(BackendRenderTarget& target, RenderStates states) const = 0; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public: + + /// One of the menu items was clicked. + /// Optional parameters: + /// - The text of the clicked menu item + /// - List containing both the name of the menu and the menu item that was clicked + SignalItemHierarchy onMenuItemClick = {"MenuItemClicked"}; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + protected: + + std::shared_ptr m_openMenuPlaceholder; + + float m_minimumMenuWidth = 125; + + Sprite m_spriteItemBackground; + Sprite m_spriteSelectedItemBackground; + + // Cached renderer properties + Color m_backgroundColorCached; + Color m_selectedBackgroundColorCached; + Color m_textColorCached; + Color m_selectedTextColorCached; + Color m_textColorDisabledCached; + Color m_separatorColorCached = Color::Black; + float m_separatorThicknessCached = 1; + float m_separatorVerticalPaddingCached = 0; + float m_separatorSidePaddingCached = 0; + float m_distanceToSideCached = 0; + + bool m_invertedMenuDirection = false; // Only used by MenuBar + + friend class OpenMenuPlaceholder; + }; + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Widget that is added to a container when the user clicks on the menu bar. This widget will be added in front of + /// all other widgets to ensure that the menus from the menu bar are always drawn in front of other widgets. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class OpenMenuPlaceholder : public Widget + { + public: + + // Instances of this class can't be copied + OpenMenuPlaceholder(const OpenMenuPlaceholder&) = delete; + OpenMenuPlaceholder& operator=(const OpenMenuPlaceholder&) = delete; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Constructor + /// @param menuWidget The widget that owns this menu + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + OpenMenuPlaceholder(MenuWidgetBase* menuWidget); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the entire size that the widget is using + /// + /// @return Full size of the widget + /// + /// This OpenMenuPlaceholder widget will try to fit the entire screen to absorb all mouse events. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f getFullSize() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the distance between the position where the widget is drawn and where the widget is placed + /// + /// @return Offset of the widget + /// + /// The offset equals -getPosition() for OpenMenuPlaceholder because it tries to fill the entire screen. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f getWidgetOffset() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of an open menu + /// @return Is the mouse on top of an open menu from the menu bar? + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool isMouseOnWidget(Vector2f pos) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Draw the widget to a render target + /// + /// @param target Render target to draw to + /// @param states Current render states + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void draw(BackendRenderTarget& target, RenderStates states) const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void leftMouseButtonNoLongerDown() override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void mouseMoved(Vector2f pos) override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Makes a copy of the widget + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Widget::Ptr clone() const override; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + private: + MenuWidgetBase* m_menuWidget; + bool m_mouseWasOnMenuWidget = true; // When a menu opens then the mouse will be on top of the menu bar + }; + + using MenuBarMenuPlaceholder TGUI_DEPRECATED("Use OpenMenuPlaceholder instead") = OpenMenuPlaceholder; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // TGUI_MENU_WIDGET_BASE_HPP diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38ab6daeb..4c14d1c34 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,7 @@ set(TGUI_SRC Renderers/ListBoxRenderer.cpp Renderers/ListViewRenderer.cpp Renderers/MenuBarRenderer.cpp + Renderers/MenuWidgetBaseRenderer.cpp Renderers/MessageBoxRenderer.cpp Renderers/PanelRenderer.cpp Renderers/PanelListBoxRenderer.cpp @@ -106,6 +107,7 @@ set(TGUI_SRC Widgets/ClickableWidget.cpp Widgets/ColorPicker.cpp Widgets/ComboBox.cpp + Widgets/ContextMenu.cpp Widgets/EditBox.cpp Widgets/EditBoxSlider.cpp Widgets/FileDialog.cpp @@ -120,6 +122,7 @@ set(TGUI_SRC Widgets/ListBox.cpp Widgets/ListView.cpp Widgets/MenuBar.cpp + Widgets/MenuWidgetBase.cpp Widgets/MessageBox.cpp Widgets/Panel.cpp Widgets/PanelListBox.cpp @@ -264,6 +267,7 @@ set(TGUI_HEADERS "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ChildWindowRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ColorPickerRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ComboBoxRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ContextMenuRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/EditBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/FileDialogRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/GroupRenderer.hpp" @@ -272,6 +276,7 @@ set(TGUI_HEADERS "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ListBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/ListViewRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MenuBarRenderer.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MenuWidgetBaseRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/MessageBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PanelListBoxRenderer.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Renderers/PanelRenderer.hpp" @@ -302,6 +307,7 @@ set(TGUI_HEADERS "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ClickableWidget.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ColorPicker.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ComboBox.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ContextMenu.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/EditBoxSlider.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/FileDialog.hpp" @@ -316,6 +322,7 @@ set(TGUI_HEADERS "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ListBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/ListView.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MenuBar.hpp" + "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MenuWidgetBase.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/MessageBox.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/Panel.hpp" "${PROJECT_SOURCE_DIR}/include/TGUI/Widgets/PanelListBox.hpp" diff --git a/src/Loading/Theme.cpp b/src/Loading/Theme.cpp index 91ae58515..b7f6b692d 100644 --- a/src/Loading/Theme.cpp +++ b/src/Loading/Theme.cpp @@ -123,6 +123,14 @@ namespace tgui {"ArrowColorHover", Color::Black}, {"ArrowBackgroundColor", Color{245, 245, 245}}, {"ArrowBackgroundColorHover", Color::White}})}, + {"ContextMenu", RendererData::create({{"TextColor", Color{60, 60, 60}}, + {"SelectedTextColor", Color::White}, + {"BackgroundColor", Color::White}, + {"SelectedBackgroundColor", Color{0, 110, 255}}, + {"TextColorDisabled", Color{125, 125, 125}}, + {"SeparatorColor", Color::Black}, + {"SeparatorThickness", 1.f}, + {"SeparatorVerticalPadding", 1.f}})}, {"EditBox", RendererData::create({{"Borders", Borders{1}}, {"Padding", Padding{0}}, {"CaretWidth", 1.f}, @@ -396,6 +404,13 @@ namespace tgui {"BorderColor", ""}, {"Borders", ""}, }}, + {"ContextMenu", { + {"BackgroundColor", ""}, + {"SelectedBackgroundColor", ""}, + {"TextColor", ""}, + {"SelectedTextColor", ""}, + {"SeparatorColor", "BorderColor"}, + }}, {"EditBox", { {"TextColor", ""}, {"TextColorDisabled", ""}, diff --git a/src/Loading/WidgetFactory.cpp b/src/Loading/WidgetFactory.cpp index 340454024..1afad767d 100644 --- a/src/Loading/WidgetFactory.cpp +++ b/src/Loading/WidgetFactory.cpp @@ -39,6 +39,7 @@ namespace tgui {"ClickableWidget", std::make_shared}, {"ColorPicker", std::make_shared}, {"ComboBox", std::make_shared}, + {"ContextMenu", std::make_shared}, {"EditBox", std::make_shared}, {"EditBoxSlider", std::make_shared}, {"FileDialog", std::make_shared}, diff --git a/src/Renderers/MenuBarRenderer.cpp b/src/Renderers/MenuBarRenderer.cpp index af10e1d30..181a2f16d 100644 --- a/src/Renderers/MenuBarRenderer.cpp +++ b/src/Renderers/MenuBarRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -29,21 +29,7 @@ namespace tgui { - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, BackgroundColor, Color::White) - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, SelectedBackgroundColor, Color(0, 110, 255)) - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, TextColor, Color::Black) - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, SelectedTextColor, Color::White) - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, TextColorDisabled, {}) - TGUI_RENDERER_PROPERTY_COLOR(MenuBarRenderer, SeparatorColor, Color::Black) - TGUI_RENDERER_PROPERTY_TEXTURE(MenuBarRenderer, TextureBackground) - TGUI_RENDERER_PROPERTY_TEXTURE(MenuBarRenderer, TextureItemBackground) - TGUI_RENDERER_PROPERTY_TEXTURE(MenuBarRenderer, TextureSelectedItemBackground) - - TGUI_RENDERER_PROPERTY_NUMBER(MenuBarRenderer, DistanceToSide, 0) - TGUI_RENDERER_PROPERTY_NUMBER(MenuBarRenderer, SeparatorThickness, 1) - TGUI_RENDERER_PROPERTY_NUMBER(MenuBarRenderer, SeparatorVerticalPadding, 0) - TGUI_RENDERER_PROPERTY_NUMBER(MenuBarRenderer, SeparatorSidePadding, 0) } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Renderers/MenuWidgetBaseRenderer.cpp b/src/Renderers/MenuWidgetBaseRenderer.cpp new file mode 100644 index 000000000..d09c26bc2 --- /dev/null +++ b/src/Renderers/MenuWidgetBaseRenderer.cpp @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace tgui +{ + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, BackgroundColor, Color::White) + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, SelectedBackgroundColor, Color(0, 110, 255)) + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, TextColor, Color::Black) + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, SelectedTextColor, Color::White) + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, TextColorDisabled, {}) + TGUI_RENDERER_PROPERTY_COLOR(MenuWidgetBaseRenderer, SeparatorColor, Color::Black) + + TGUI_RENDERER_PROPERTY_TEXTURE(MenuWidgetBaseRenderer, TextureItemBackground) + TGUI_RENDERER_PROPERTY_TEXTURE(MenuWidgetBaseRenderer, TextureSelectedItemBackground) + + TGUI_RENDERER_PROPERTY_NUMBER(MenuWidgetBaseRenderer, DistanceToSide, 0) + TGUI_RENDERER_PROPERTY_NUMBER(MenuWidgetBaseRenderer, SeparatorThickness, 1) + TGUI_RENDERER_PROPERTY_NUMBER(MenuWidgetBaseRenderer, SeparatorVerticalPadding, 0) + TGUI_RENDERER_PROPERTY_NUMBER(MenuWidgetBaseRenderer, SeparatorSidePadding, 0) +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/ContextMenu.cpp b/src/Widgets/ContextMenu.cpp new file mode 100644 index 000000000..00af6c018 --- /dev/null +++ b/src/Widgets/ContextMenu.cpp @@ -0,0 +1,515 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#if !TGUI_EXPERIMENTAL_USE_STD_MODULE + #include +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if TGUI_COMPILED_WITH_CPP_VER < 17 + constexpr const char ContextMenu::StaticWidgetType[]; +#endif + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ContextMenu::ContextMenu(const char* typeName, bool initRenderer) : + MenuWidgetBase{typeName, false} + { + if (initRenderer) + { + m_renderer = aurora::makeCopied(); + setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + } + + setTextSize(getGlobalTextSize()); + setItemHeight(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f)); + setMinimumMenuWidth((Text::getLineHeight(m_fontCached, m_textSizeCached) * 4) + (2 * m_distanceToSideCached)); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ContextMenu::Ptr ContextMenu::create() + { + return std::make_shared(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ContextMenu::Ptr ContextMenu::copy(const ContextMenu::ConstPtr& menuBar) + { + if (menuBar) + return std::static_pointer_cast(menuBar->clone()); + else + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ContextMenuRenderer* ContextMenu::getSharedRenderer() + { + return aurora::downcast(MenuWidgetBase::getSharedRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + const ContextMenuRenderer* ContextMenu::getSharedRenderer() const + { + return aurora::downcast(MenuWidgetBase::getSharedRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ContextMenuRenderer* ContextMenu::getRenderer() + { + return aurora::downcast(MenuWidgetBase::getRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::isMenuOpen() const + { + return m_menuOpen; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::openMenu() + { + closeMenu(); + + m_menuOpen = true; + + if (m_parent) + { + // Find the RootContainer that contains the menu bar + Vector2f scale = getScale(); + Container* container = m_parent; + while (container->getParent() != nullptr) + { + scale.x *= container->getScale().x; + scale.y *= container->getScale().y; + container = container->getParent(); + } + + m_openMenuPlaceholder->setPosition(getAbsolutePosition()); + m_openMenuPlaceholder->setScale(scale); + container->add(m_openMenuPlaceholder, "#TGUI_INTERNAL$OpenMenuPlaceholder#"); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::openMenu(Vector2f position) + { + setPosition(position); + openMenu(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::closeMenu() + { + if (!m_menuOpen) + return; + + closeSubMenus(m_menu.menuItems, m_menu.selectedMenuItem); + m_menuOpen = false; + + if (m_openMenuPlaceholder->getParent()) + m_openMenuPlaceholder->getParent()->remove(m_openMenuPlaceholder); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::setSize(const Layout2d&) + { + // Manually changing the size is not possible, the context menu is always auto-sized + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::setEnabled(bool enabled) + { + if (m_enabled == enabled) + return; + + Widget::setEnabled(enabled); + + if (!enabled) + closeMenu(); + + updateTextColors(m_menu.menuItems, m_menu.selectedMenuItem); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::setItemHeight(float itemHeight) + { + m_itemHeight = itemHeight; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float ContextMenu::getItemHeight() const + { + return m_itemHeight; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::addMenuItem(const String& text) + { + createMenu(m_menu.menuItems, text); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::addMenuItem(const std::vector& hierarchy, bool createParents) + { + if (hierarchy.empty()) + return false; + + if (hierarchy.size() == 1) + { + createMenu(m_menu.menuItems, hierarchy.back()); + return true; + } + + auto* menu = findMenuItemParent(hierarchy, 0, m_menu.menuItems, createParents); + if (!menu) + return false; + + createMenu(menu->menuItems, hierarchy.back()); + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::changeMenuItem(const std::vector& hierarchy, const String& text) + { + if (hierarchy.empty()) + return false; + + auto* menu = findMenuItem(hierarchy, m_menu.menuItems); + if (!menu) + return false; + + menu->text.setString(text); + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::removeAllMenuItems() + { + m_menu.menuItems.clear(); + m_menu.selectedMenuItem = -1; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::removeMenuItem(const String& menuItem) + { + return removeMenuItem(std::vector{menuItem}, false); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::removeMenuItem(const std::vector& hierarchy, bool removeParentsWhenEmpty) + { + if (hierarchy.empty()) + return false; + + return removeMenuImpl(hierarchy, removeParentsWhenEmpty, 0, m_menu.menuItems); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::removeSubMenuItems(const std::vector& hierarchy) + { + if (hierarchy.empty()) + return false; + + return removeSubMenusImpl(hierarchy, 0, m_menu.menuItems); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::setMenuItemEnabled(const String& menuItem, bool enabled) + { + return setMenuItemEnabled(std::vector{menuItem}, enabled); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::setMenuItemEnabled(const std::vector& hierarchy, bool enabled) + { + if (hierarchy.empty()) + return false; + + Menu* menu = &m_menu; + if (hierarchy.size() >= 2) + { + menu = findMenuItemParent(hierarchy, 0, m_menu.menuItems, false); + if (!menu) + return false; + } + + for (unsigned int j = 0; j < menu->menuItems.size(); ++j) + { + auto& menuItem = menu->menuItems[j]; + if (menuItem.text.getString() != hierarchy.back()) + continue; + + if (!enabled && (menu->selectedMenuItem == static_cast(j))) + menu->selectedMenuItem = -1; + + menuItem.enabled = enabled; + updateMenuTextColor(menuItem, (menu->selectedMenuItem == static_cast(j))); + return true; + } + + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::getMenuItemEnabled(const String& menuItem) const + { + return getMenuItemEnabled(std::vector{menuItem}); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::getMenuItemEnabled(const std::vector& hierarchy) const + { + if (hierarchy.empty()) + return false; + + auto* menuItem = findMenuItem(hierarchy, m_menu.menuItems); + if (!menuItem) + return false; + + return menuItem->enabled; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::setMinimumMenuWidth(float minimumWidth) + { + m_minimumMenuWidth = minimumWidth; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float ContextMenu::getMinimumMenuWidth() const + { + return m_minimumMenuWidth; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + std::vector ContextMenu::getMenuItems() const + { + return getMenusImpl(m_menu.menuItems); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::isMouseOnWidget(Vector2f) const + { + // The widget can't be interacted with directly. + // When the menu is open then the OpenMenuPlaceholder will intercept the mouse event and forward it to this class. + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::draw(BackendRenderTarget&, RenderStates) const + { + // Nothing is drawn here. + // When the menu is open then the OpenMenuPlaceholder will call the drawOpenMenu function to do the rendering. + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::rendererChanged(const String& property) + { + if (property == U"TextColor") + { + m_textColorCached = getSharedRenderer()->getTextColor(); + updateTextColors(m_menu.menuItems, m_menu.selectedMenuItem); + } + else if (property == U"SelectedTextColor") + { + m_selectedTextColorCached = getSharedRenderer()->getSelectedTextColor(); + updateTextColors(m_menu.menuItems, m_menu.selectedMenuItem); + } + else if (property == U"TextColorDisabled") + { + m_textColorDisabledCached = getSharedRenderer()->getTextColorDisabled(); + updateTextColors(m_menu.menuItems, m_menu.selectedMenuItem); + } + else if ((property == U"Opacity") || (property == U"OpacityDisabled")) + { + Widget::rendererChanged(property); + updateTextOpacity(m_menu.menuItems); + } + else if (property == U"Font") + { + Widget::rendererChanged(property); + updateTextFont(m_menu.menuItems); + } + else + MenuWidgetBase::rendererChanged(property); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + std::unique_ptr ContextMenu::save(SavingRenderersMap& renderers) const + { + auto node = MenuWidgetBase::save(renderers); + saveMenus(node, m_menu.menuItems); + node->propertyValuePairs[U"MinimumMenuWidth"] = std::make_unique(String::fromNumber(m_minimumMenuWidth)); + node->propertyValuePairs[U"ItemHeight"] = std::make_unique(String::fromNumber(m_itemHeight)); + return node; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::load(const std::unique_ptr& node, const LoadingRenderersMap& renderers) + { + MenuWidgetBase::load(node, renderers); + + loadMenus(node, m_menu.menuItems); + m_menu.selectedMenuItem = -1; + + // Remove the 'menu' nodes as they have been processed + node->children.erase(std::remove_if(node->children.begin(), node->children.end(), + [](const std::unique_ptr& child){ return child->name == U"Menu"; }), node->children.end()); + + if (node->propertyValuePairs[U"MinimumMenuWidth"]) + setMinimumMenuWidth(node->propertyValuePairs[U"MinimumMenuWidth"]->value.toFloat()); + if (node->propertyValuePairs[U"ItemHeight"]) + setItemHeight(node->propertyValuePairs[U"ItemHeight"]->value.toFloat()); + + // Update the text colors to properly display disabled menus + updateTextColors(m_menu.menuItems, m_menu.selectedMenuItem); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::updateTextSize() + { + setTextSizeImpl(m_menu.menuItems, m_textSizeCached); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Widget::Ptr ContextMenu::clone() const + { + return std::make_shared(*this); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::drawOpenMenu(BackendRenderTarget& target, RenderStates states) const + { + TGUI_ASSERT(m_menuOpen, "ContextMenu::drawOpenMenu can only be called when the menu is open"); + MenuWidgetBase::drawOpenMenu(target, states, m_menu, {0, 0}); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::emitMenuItemClick(const std::vector& hierarchy) + { + TGUI_ASSERT(hierarchy.size() >= 2, "hierarchy must contain at least 2 elements in ContextMenu::emitMenuItemClick"); + TGUI_ASSERT(hierarchy.front().empty(), "hierarchy must start with an empty element in ContextMenu::emitMenuItemClick"); + + // The fist element of the hierarchy is always empty due to the way we stored it (which is done because the code + // originated from MenuBar where there are multiple named menus, while ContextMenu uses a single unnamed menu). + std::vector correctedHierarchy = hierarchy; + correctedHierarchy.erase(correctedHierarchy.begin()); + + onMenuItemClick.emit(this, correctedHierarchy.back(), correctedHierarchy); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::deselectDeepestItem() + { + TGUI_ASSERT(m_menuOpen, "ContextMenu::deselectDeepestItem can only be called when the menu is open"); + MenuWidgetBase::deselectDeepestItem(&m_menu); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool ContextMenu::isMouseOnOpenMenu(Vector2f pos) const + { + // If the menu isn't open then the mouse can't be on top of it + if (!m_menuOpen) + return false; + + return MenuWidgetBase::isMouseOnOpenMenu(pos, m_menu, {0, 0}); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float ContextMenu::getDefaultMenuItemHeight() const + { + return m_itemHeight; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::leftMouseReleasedOnMenu() + { + // This function may be called while closing the menu (when removing the placeholder widget) + if (!m_menuOpen) + return; + + MenuWidgetBase::leftMouseReleasedOnMenu(&m_menu); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ContextMenu::mouseMovedOnMenu(Vector2f pos) + { + TGUI_ASSERT(m_menuOpen, "ContextMenu::mouseMovedOnMenu can only be called when the menu is open"); + + MenuWidgetBase::mouseMovedOnMenu(pos, m_menu, {0, 0}); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/MenuBar.cpp b/src/Widgets/MenuBar.cpp index 815d14062..d4cab6c99 100644 --- a/src/Widgets/MenuBar.cpp +++ b/src/Widgets/MenuBar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -33,137 +33,6 @@ namespace tgui { - namespace - { - bool isSeparator(const MenuBar::Menu& menuItem) - { - return menuItem.text.getString() == U"-"; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - bool removeMenuImpl(const std::vector& hierarchy, bool removeParentsWhenEmpty, unsigned int parentIndex, std::vector& menus) - { - for (auto it = menus.begin(); it != menus.end(); ++it) - { - if (it->text.getString() != hierarchy[parentIndex]) - continue; - - if (parentIndex + 1 == hierarchy.size()) - { - menus.erase(it); - return true; - } - else - { - // Return false if some menu in the hierarchy couldn't be found - if (!removeMenuImpl(hierarchy, removeParentsWhenEmpty, parentIndex + 1, it->menuItems)) - return false; - - // If parents don't have to be removed as well then we are done - if (!removeParentsWhenEmpty) - return true; - - // Also delete the parent if empty - if (it->menuItems.empty()) - menus.erase(it); - - return true; - } - } - - // The hierarchy doesn't exist - return false; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - bool removeSubMenusImpl(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus) - { - for (auto& menu : menus) - { - if (menu.text.getString() != hierarchy[parentIndex]) - continue; - - if (parentIndex + 1 == hierarchy.size()) - { - menu.menuItems.clear(); - return true; - } - else - return removeSubMenusImpl(hierarchy, parentIndex + 1, menu.menuItems); - } - - // The hierarchy doesn't exist - return false; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void setTextSizeImpl(std::vector& menus, unsigned int textSize) - { - for (auto& menu : menus) - { - menu.text.setCharacterSize(textSize); - if (!menu.menuItems.empty()) - setTextSizeImpl(menu.menuItems, textSize); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - std::vector getMenusImpl(const std::vector& menus) - { - std::vector menuElements; - - for (const auto& menu : menus) - { - TGUI_EMPLACE_BACK(element, menuElements) - element.text = menu.text.getString(); - element.enabled = menu.enabled; - if (!menu.menuItems.empty()) - element.menuItems = getMenusImpl(menu.menuItems); - } - - return menuElements; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void saveMenus(const std::unique_ptr& parentNode, const std::vector& menus) - { - for (const auto& menu : menus) - { - auto menuNode = std::make_unique(); - menuNode->name = "Menu"; - - menuNode->propertyValuePairs[U"Text"] = std::make_unique(Serializer::serialize(menu.text.getString())); - if (!menu.enabled) - menuNode->propertyValuePairs[U"Enabled"] = std::make_unique(Serializer::serialize(menu.enabled)); - - if (!menu.menuItems.empty()) - { - // Save as nested 'Menu' sections only when needed, use the more compact string list when just storing the menu items - const bool recursionNeeded = std::any_of(menu.menuItems.begin(), menu.menuItems.end(), - [](const MenuBar::Menu& menuItem){ return !menuItem.enabled || !menuItem.menuItems.empty(); }); - if (recursionNeeded) - saveMenus(menuNode, menu.menuItems); - else - { - String itemList = "[" + Serializer::serialize(menu.menuItems[0].text.getString()); - for (std::size_t i = 1; i < menu.menuItems.size(); ++i) - itemList += ", " + Serializer::serialize(menu.menuItems[i].text.getString()); - itemList += "]"; - - menuNode->propertyValuePairs[U"Items"] = std::make_unique(itemList); - } - } - - parentNode->children.push_back(std::move(menuNode)); - } - } - } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if TGUI_COMPILED_WITH_CPP_VER < 17 @@ -173,9 +42,7 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MenuBar::MenuBar(const char* typeName, bool initRenderer) : - Widget{typeName, false}, - m_menuWidgetPlaceholder(std::make_shared(this)), - m_distanceToSideCached(std::round(Text::getLineHeight(m_fontCached, getGlobalTextSize()) * 0.4f)) + MenuWidgetBase{typeName, false} { if (initRenderer) { @@ -190,101 +57,6 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar::MenuBar(const MenuBar& other) : - Widget {other}, - m_menus {other.m_menus}, - m_menuWidgetPlaceholder {std::make_shared(this)}, - m_visibleMenu {other.m_visibleMenu}, - m_minimumSubMenuWidth {other.m_minimumSubMenuWidth}, - m_invertedMenuDirection {other.m_invertedMenuDirection}, - m_spriteBackground {other.m_spriteBackground}, - m_spriteItemBackground {other.m_spriteItemBackground}, - m_spriteSelectedItemBackground {other.m_spriteSelectedItemBackground}, - m_backgroundColorCached {other.m_backgroundColorCached}, - m_selectedBackgroundColorCached{other.m_selectedBackgroundColorCached}, - m_textColorCached {other.m_textColorCached}, - m_selectedTextColorCached {other.m_selectedTextColorCached}, - m_textColorDisabledCached {other.m_textColorDisabledCached}, - m_distanceToSideCached {other.m_distanceToSideCached} - { - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBar::MenuBar(MenuBar&& other) noexcept : - Widget {std::move(other)}, - m_menus {std::move(other.m_menus)}, - m_menuWidgetPlaceholder {std::make_shared(this)}, - m_visibleMenu {std::move(other.m_visibleMenu)}, - m_minimumSubMenuWidth {std::move(other.m_minimumSubMenuWidth)}, - m_invertedMenuDirection {std::move(other.m_invertedMenuDirection)}, - m_spriteBackground {std::move(other.m_spriteBackground)}, - m_spriteItemBackground {std::move(other.m_spriteItemBackground)}, - m_spriteSelectedItemBackground {std::move(other.m_spriteSelectedItemBackground)}, - m_backgroundColorCached {std::move(other.m_backgroundColorCached)}, - m_selectedBackgroundColorCached{std::move(other.m_selectedBackgroundColorCached)}, - m_textColorCached {std::move(other.m_textColorCached)}, - m_selectedTextColorCached {std::move(other.m_selectedTextColorCached)}, - m_textColorDisabledCached {std::move(other.m_textColorDisabledCached)}, - m_distanceToSideCached {std::move(other.m_distanceToSideCached)} - { - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBar& MenuBar::operator=(const MenuBar& other) - { - // Make sure it is not the same widget - if (this != &other) - { - Widget::operator=(other); - m_menus = other.m_menus; - m_menuWidgetPlaceholder = other.m_menuWidgetPlaceholder; - m_visibleMenu = other.m_visibleMenu; - m_minimumSubMenuWidth = other.m_minimumSubMenuWidth; - m_invertedMenuDirection = other.m_invertedMenuDirection; - m_spriteBackground = other.m_spriteBackground; - m_spriteItemBackground = other.m_spriteItemBackground; - m_spriteSelectedItemBackground = other.m_spriteSelectedItemBackground; - m_backgroundColorCached = other.m_backgroundColorCached; - m_selectedBackgroundColorCached = other.m_selectedBackgroundColorCached; - m_textColorCached = other.m_textColorCached; - m_selectedTextColorCached = other.m_selectedTextColorCached; - m_textColorDisabledCached = other.m_textColorDisabledCached; - m_distanceToSideCached = other.m_distanceToSideCached; - } - - return *this; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBar& MenuBar::operator=(MenuBar&& other) noexcept - { - if (this != &other) - { - m_menus = std::move(other.m_menus); - m_menuWidgetPlaceholder = std::move(other.m_menuWidgetPlaceholder); - m_visibleMenu = std::move(other.m_visibleMenu); - m_minimumSubMenuWidth = std::move(other.m_minimumSubMenuWidth); - m_invertedMenuDirection = std::move(other.m_invertedMenuDirection); - m_spriteBackground = std::move(other.m_spriteBackground); - m_spriteItemBackground = std::move(other.m_spriteItemBackground); - m_spriteSelectedItemBackground = std::move(other.m_spriteSelectedItemBackground); - m_backgroundColorCached = std::move(other.m_backgroundColorCached); - m_selectedBackgroundColorCached = std::move(other.m_selectedBackgroundColorCached); - m_textColorCached = std::move(other.m_textColorCached); - m_selectedTextColorCached = std::move(other.m_selectedTextColorCached); - m_textColorDisabledCached = std::move(other.m_textColorDisabledCached); - m_distanceToSideCached = std::move(other.m_distanceToSideCached); - Widget::operator=(std::move(other)); - } - - return *this; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MenuBar::Ptr MenuBar::create() { return std::make_shared(); @@ -304,28 +76,28 @@ namespace tgui MenuBarRenderer* MenuBar::getSharedRenderer() { - return aurora::downcast(Widget::getSharedRenderer()); + return aurora::downcast(MenuWidgetBase::getSharedRenderer()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const MenuBarRenderer* MenuBar::getSharedRenderer() const { - return aurora::downcast(Widget::getSharedRenderer()); + return aurora::downcast(MenuWidgetBase::getSharedRenderer()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MenuBarRenderer* MenuBar::getRenderer() { - return aurora::downcast(Widget::getRenderer()); + return aurora::downcast(MenuWidgetBase::getRenderer()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MenuBar::setSize(const Layout2d& size) { - Widget::setSize(size); + MenuWidgetBase::setSize(size); m_spriteBackground.setSize(getSize()); } @@ -337,7 +109,7 @@ namespace tgui if (m_enabled == enabled) return; - Widget::setEnabled(enabled); + MenuWidgetBase::setEnabled(enabled); if (!enabled) closeMenu(); @@ -376,7 +148,7 @@ namespace tgui if (hierarchy.size() < 2) return false; - auto* menu = findMenu(hierarchy, 0, m_menus, createParents); + auto* menu = findMenuItemParent(hierarchy, 0, m_menus, createParents); if (!menu) return false; @@ -391,7 +163,7 @@ namespace tgui if (hierarchy.empty()) return false; - auto* menu = findMenuItem(hierarchy); + auto* menu = findMenuItem(hierarchy, m_menus); if (!menu) return false; @@ -505,7 +277,7 @@ namespace tgui if (hierarchy.size() < 2) return false; - auto* menu = findMenu(hierarchy, 0, m_menus, false); + auto* menu = findMenuItemParent(hierarchy, 0, m_menus, false); if (!menu) return false; @@ -540,7 +312,7 @@ namespace tgui if (hierarchy.size() < 2) return false; - auto* menuItem = findMenuItem(hierarchy); + auto* menuItem = findMenuItem(hierarchy, m_menus); if (!menuItem) return false; @@ -558,14 +330,14 @@ namespace tgui void MenuBar::setMinimumSubMenuWidth(float minimumWidth) { - m_minimumSubMenuWidth = minimumWidth; + m_minimumMenuWidth = minimumWidth; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float MenuBar::getMinimumSubMenuWidth() const { - return m_minimumSubMenuWidth; + return m_minimumMenuWidth; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -584,7 +356,7 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - std::vector MenuBar::getMenus() const + std::vector MenuBar::getMenus() const { return getMenusImpl(m_menus); } @@ -610,9 +382,9 @@ namespace tgui container = container->getParent(); } - m_menuWidgetPlaceholder->setPosition(getAbsolutePosition()); - m_menuWidgetPlaceholder->setScale(scale); - container->add(m_menuWidgetPlaceholder, "#TGUI_INTERNAL$MenuBarMenuPlaceholder#"); + m_openMenuPlaceholder->setPosition(getAbsolutePosition()); + m_openMenuPlaceholder->setScale(scale); + container->add(m_openMenuPlaceholder, "#TGUI_INTERNAL$OpenMenuPlaceholder#"); } } @@ -625,8 +397,8 @@ namespace tgui closeSubMenus(m_menus, m_visibleMenu); - if (m_menuWidgetPlaceholder->getParent()) - m_menuWidgetPlaceholder->getParent()->remove(m_menuWidgetPlaceholder); + if (m_openMenuPlaceholder->getParent()) + m_openMenuPlaceholder->getParent()->remove(m_openMenuPlaceholder); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -640,7 +412,7 @@ namespace tgui bool MenuBar::leftMousePressed(Vector2f pos) { - Widget::leftMousePressed(pos); + MenuWidgetBase::leftMousePressed(pos); pos -= getPosition(); @@ -742,17 +514,7 @@ namespace tgui // The mouse is to the right of all menus, deselect the selected item of the deepest submenu if (!handled) - deselectBottomItem(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - Signal& MenuBar::getSignal(String signalName) - { - if (signalName == onMenuItemClick.getName()) - return onMenuItemClick; - else - return Widget::getSignal(std::move(signalName)); + deselectDeepestItem(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -778,66 +540,30 @@ namespace tgui { m_spriteBackground.setTexture(getSharedRenderer()->getTextureBackground()); } - else if (property == U"TextureItemBackground") - { - m_spriteItemBackground.setTexture(getSharedRenderer()->getTextureItemBackground()); - } - else if (property == U"TextureSelectedItemBackground") - { - m_spriteSelectedItemBackground.setTexture(getSharedRenderer()->getTextureSelectedItemBackground()); - } - else if (property == U"BackgroundColor") - { - m_backgroundColorCached = getSharedRenderer()->getBackgroundColor(); - } - else if (property == U"SelectedBackgroundColor") - { - m_selectedBackgroundColorCached = getSharedRenderer()->getSelectedBackgroundColor(); - } - else if (property == U"DistanceToSide") - { - m_distanceToSideCached = getSharedRenderer()->getDistanceToSide(); - } - else if (property == U"SeparatorColor") - { - m_separatorColorCached = getSharedRenderer()->getSeparatorColor(); - } - else if (property == U"SeparatorThickness") - { - m_separatorThicknessCached = getSharedRenderer()->getSeparatorThickness(); - } - else if (property == U"SeparatorVerticalPadding") - { - m_separatorVerticalPaddingCached = getSharedRenderer()->getSeparatorVerticalPadding(); - } - else if (property == U"SeparatorSidePadding") - { - m_separatorSidePaddingCached = getSharedRenderer()->getSeparatorSidePadding(); - } else if ((property == U"Opacity") || (property == U"OpacityDisabled")) { - Widget::rendererChanged(property); + MenuWidgetBase::rendererChanged(property); updateTextOpacity(m_menus); m_spriteBackground.setOpacity(m_opacityCached); } else if (property == U"Font") { - Widget::rendererChanged(property); + MenuWidgetBase::rendererChanged(property); updateTextFont(m_menus); } else - Widget::rendererChanged(property); + MenuWidgetBase::rendererChanged(property); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// std::unique_ptr MenuBar::save(SavingRenderersMap& renderers) const { - auto node = Widget::save(renderers); + auto node = MenuWidgetBase::save(renderers); saveMenus(node, m_menus); - node->propertyValuePairs[U"MinimumSubMenuWidth"] = std::make_unique(String::fromNumber(m_minimumSubMenuWidth)); + node->propertyValuePairs[U"MinimumSubMenuWidth"] = std::make_unique(String::fromNumber(m_minimumMenuWidth)); if (m_invertedMenuDirection) node->propertyValuePairs[U"InvertedMenuDirection"] = std::make_unique("true"); @@ -848,7 +574,7 @@ namespace tgui void MenuBar::load(const std::unique_ptr& node, const LoadingRenderersMap& renderers) { - Widget::load(node, renderers); + MenuWidgetBase::load(node, renderers); if (node->propertyValuePairs[U"MinimumSubMenuWidth"]) setMinimumSubMenuWidth(node->propertyValuePairs[U"MinimumSubMenuWidth"]->value.toFloat()); @@ -883,373 +609,43 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void MenuBar::drawOpenMenu(BackendRenderTarget& target, RenderStates states) const + Vector2f MenuBar::calculateMenuOffset(std::size_t visibleMenuIdx) const { - TGUI_ASSERT(m_visibleMenu >= 0, "MenuBar::drawOpenMenu can only be called when a menu is open"); - const auto visibleMenuIdx = static_cast(m_visibleMenu); - - // Find the position of the menu - float leftOffset = 0; + Vector2f menuOffset; for (std::size_t i = 0; i < visibleMenuIdx; ++i) - leftOffset += m_menus[i].text.getSize().x + (2 * m_distanceToSideCached); - - // Move the menu to the left if it otherwise falls off the screen - bool openSubMenuToRight = true; - const float menuWidth = calculateMenuWidth(m_menus[visibleMenuIdx]); - if (getParent() && (getPosition().x + leftOffset + menuWidth > getParent()->getInnerSize().x)) - { - leftOffset = std::max(0.f, getParent()->getInnerSize().x - menuWidth); - openSubMenuToRight = false; - } + menuOffset.x += m_menus[i].text.getSize().x + (2 * m_distanceToSideCached); if (m_invertedMenuDirection) - states.transform.translate({leftOffset, -calculateOpenMenuHeight(m_menus[visibleMenuIdx].menuItems)}); + menuOffset.y = -calculateOpenMenuHeight(m_menus[visibleMenuIdx].menuItems); else - states.transform.translate({leftOffset, getSize().y}); - - drawMenu(target, states, m_menus[visibleMenuIdx], menuWidth, getPosition().x + leftOffset, openSubMenuToRight); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::createMenu(std::vector& menus, const String& text) - { - Menu newMenu; - newMenu.text.setFont(m_fontCached); - newMenu.text.setColor(m_textColorCached); - newMenu.text.setOpacity(m_opacityCached); - newMenu.text.setCharacterSize(m_textSizeCached); - newMenu.text.setString(text); - menus.push_back(std::move(newMenu)); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBar::Menu* MenuBar::findMenu(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus, bool createParents) - { - assert(hierarchy.size() >= 2); - - for (auto& menu : menus) - { - if (menu.text.getString() != hierarchy[parentIndex]) - continue; - - if (parentIndex + 2 == hierarchy.size()) - return &menu; - else - return findMenu(hierarchy, parentIndex + 1, menu.menuItems, createParents); - } - - if (createParents) - { - createMenu(menus, hierarchy[parentIndex]); - if (parentIndex + 2 == hierarchy.size()) - return &menus.back(); - else - return findMenu(hierarchy, parentIndex + 1, menus.back().menuItems, createParents); - } - - return nullptr; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - const MenuBar::Menu* MenuBar::findMenu(const std::vector& hierarchy, unsigned int parentIndex, const std::vector& menus) const - { - assert(hierarchy.size() >= 2); - - for (auto& menu : menus) - { - if (menu.text.getString() != hierarchy[parentIndex]) - continue; - - if (parentIndex + 2 == hierarchy.size()) - return &menu; - else - return findMenu(hierarchy, parentIndex + 1, menu.menuItems); - } - - return nullptr; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBar::Menu* MenuBar::findMenuItem(const std::vector& hierarchy) - { - if (hierarchy.empty()) - return nullptr; - - std::vector* menuItems; - if (hierarchy.size() == 1) - menuItems = &m_menus; - else - { - auto* menu = findMenu(hierarchy, 0, m_menus, false); - if (!menu) - return nullptr; - - menuItems = &menu->menuItems; - } - - for (auto& menuItem : *menuItems) - { - if (menuItem.text.getString() != hierarchy.back()) - continue; - - return &menuItem; - } - - return nullptr; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - const MenuBar::Menu* MenuBar::findMenuItem(const std::vector& hierarchy) const - { - if (hierarchy.empty()) - return nullptr; - - const std::vector* menuItems; - if (hierarchy.size() == 1) - menuItems = &m_menus; - else - { - const auto* menu = findMenu(hierarchy, 0, m_menus); - if (!menu) - return nullptr; - - menuItems = &menu->menuItems; - } - - for (auto& menuItem : *menuItems) - { - if (menuItem.text.getString() != hierarchy.back()) - continue; - - return &menuItem; - } - - return nullptr; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::loadMenus(const std::unique_ptr& node, std::vector& menus) - { - for (const auto& childNode : node->children) - { - if (childNode->name != U"Menu") - continue; - - if (!childNode->propertyValuePairs[U"Text"]) - throw Exception{U"Failed to parse 'Menu' property, expected a nested 'Text' propery"}; - - const String menuText = Deserializer::deserialize(ObjectConverter::Type::String, childNode->propertyValuePairs[U"Text"]->value).getString(); - createMenu(menus, menuText); - - if (childNode->propertyValuePairs[U"Enabled"]) - menus.back().enabled = Deserializer::deserialize(ObjectConverter::Type::Bool, childNode->propertyValuePairs[U"Enabled"]->value).getBool(); - - // Recursively handle the menu nodes - if (!childNode->children.empty()) - loadMenus(childNode, menus.back().menuItems); - - // Menu items can also be stored in an string array in the 'Items' property instead of as a nested Menu section - if (childNode->propertyValuePairs[U"Items"]) - { - if (!childNode->propertyValuePairs[U"Items"]->listNode) - throw Exception{U"Failed to parse 'Items' property inside 'Menu' property, expected a list as value"}; - - for (std::size_t i = 0; i < childNode->propertyValuePairs[U"Items"]->valueList.size(); ++i) - { - const String menuItemText = Deserializer::deserialize(ObjectConverter::Type::String, childNode->propertyValuePairs[U"Items"]->valueList[i]).getString(); - createMenu(menus.back().menuItems, menuItemText); - } - } - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::closeSubMenus(std::vector& menus, int& selectedMenu) - { - if (selectedMenu < 0) - return; - - const auto selectedMenuIdx = static_cast(selectedMenu); - closeSubMenus(menus[selectedMenuIdx].menuItems, menus[selectedMenuIdx].selectedMenuItem); - - updateMenuTextColor(menus[selectedMenuIdx], false); - selectedMenu = -1; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::deselectBottomItem() - { - TGUI_ASSERT(m_visibleMenu >= 0, "MenuBar::deselectBottomItem can only be called when a menu is open"); - - auto* menu = &m_menus[static_cast(m_visibleMenu)]; - while (menu->selectedMenuItem >= 0) - { - auto& menuItem = menu->menuItems[static_cast(menu->selectedMenuItem)]; - if (menuItem.menuItems.empty()) - { - closeSubMenus(menu->menuItems, menu->selectedMenuItem); - break; - } - - menu = &menuItem; - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::updateMenuTextColor(Menu& menu, bool selected) - { - if ((!m_enabled || !menu.enabled) && m_textColorDisabledCached.isSet()) - menu.text.setColor(m_textColorDisabledCached); - else if (selected && m_selectedTextColorCached.isSet()) - menu.text.setColor(m_selectedTextColorCached); - else - menu.text.setColor(m_textColorCached); - } + menuOffset.y = getSize().y; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::updateTextColors(std::vector& menus, int selectedMenu) - { - for (std::size_t i = 0; i < menus.size(); ++i) - { - updateMenuTextColor(menus[i], (selectedMenu == static_cast(i))); - updateTextColors(menus[i].menuItems, menus[i].selectedMenuItem); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::updateTextOpacity(std::vector& menus) - { - for (auto& menu : menus) - { - menu.text.setOpacity(m_opacityCached); - updateTextOpacity(menu.menuItems); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBar::updateTextFont(std::vector& menus) - { - for (auto& menu : menus) - { - menu.text.setFont(m_fontCached); - updateTextFont(menu.menuItems); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - float MenuBar::calculateMenuWidth(const Menu& menu) const - { - float maxWidth = m_minimumSubMenuWidth; - for (const auto& item : menu.menuItems) - { - float width = item.text.getSize().x + (2.f * m_distanceToSideCached); - - // Reserve space for an arrow if there are submenus - if (!item.menuItems.empty()) - width += (getSize().y / 4.f) + m_distanceToSideCached; - - if (width > maxWidth) - maxWidth = width; - } - - return maxWidth; + return menuOffset; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - float MenuBar::getMenuItemHeight(const Menu& menuItem) const - { - if (isSeparator(menuItem)) - return m_separatorThicknessCached + 2*m_separatorVerticalPaddingCached; - else - return getSize().y; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - float MenuBar::calculateOpenMenuHeight(const std::vector& menuItems) const + void MenuBar::drawOpenMenu(BackendRenderTarget& target, RenderStates states) const { - float height = 0; - for (const auto& item : menuItems) - height += getMenuItemHeight(item); - - return height; + TGUI_ASSERT(m_visibleMenu >= 0, "MenuBar::drawOpenMenu can only be called when a menu is open"); + const auto visibleMenuIdx = static_cast(m_visibleMenu); + MenuWidgetBase::drawOpenMenu(target, states, m_menus[visibleMenuIdx], calculateMenuOffset(visibleMenuIdx)); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - Vector2f MenuBar::calculateSubmenuOffset(const Menu& menu, float globalLeftPos, float menuWidth, float subMenuWidth, bool& openSubMenuToRight) const + void MenuBar::emitMenuItemClick(const std::vector& hierarchy) { - TGUI_ASSERT(menu.selectedMenuItem >= 0, "MenuBar::calculateSubmenuOffset can only be called when the menu has an open submenu"); - const auto selectedMenuItemIdx = static_cast(menu.selectedMenuItem); - - float leftOffset; - if (openSubMenuToRight) - { - leftOffset = menuWidth; - if (getParent() && (globalLeftPos + leftOffset + subMenuWidth > getParent()->getInnerSize().x)) - { - if (globalLeftPos + leftOffset + subMenuWidth - getParent()->getInnerSize().x < globalLeftPos) - { - leftOffset = -subMenuWidth; - openSubMenuToRight = false; - } - } - } - else // Submenu opens to the left side - { - leftOffset = -subMenuWidth; - if (getParent() && (globalLeftPos < subMenuWidth)) - { - if (getParent()->getInnerSize().x - menuWidth - globalLeftPos > globalLeftPos) - { - leftOffset = menuWidth; - openSubMenuToRight = true; - } - } - } - - float topOffset = 0; - for (std::size_t i = 0; i < selectedMenuItemIdx; ++i) - topOffset += getMenuItemHeight(menu.menuItems[i]); - - if (m_invertedMenuDirection) - topOffset -= calculateOpenMenuHeight(menu.menuItems[selectedMenuItemIdx].menuItems) - getSize().y; - - return {leftOffset, topOffset}; + TGUI_ASSERT(hierarchy.size() >= 2, "hierarchy must contain at least 2 elements in MenuBar::emitMenuItemClick"); + onMenuItemClick.emit(this, hierarchy.back(), hierarchy); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool MenuBar::isMouseOnTopOfMenu(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, const Menu& menu, float menuWidth) const + void MenuBar::deselectDeepestItem() { - // Check if the mouse is on top of the menu - if (FloatRect{menuPos.x, menuPos.y, menuWidth, calculateOpenMenuHeight(menu.menuItems)}.contains(mousePos)) - return true; - - // Check if the mouse is on one of the submenus - if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) - { - const float subMenuWidth = calculateMenuWidth(menu.menuItems[static_cast(menu.selectedMenuItem)]); - const Vector2f offset = calculateSubmenuOffset(menu, menuPos.x, menuWidth, subMenuWidth, openSubMenuToRight); - if (isMouseOnTopOfMenu(menuPos + offset, mousePos, openSubMenuToRight, menu.menuItems[static_cast(menu.selectedMenuItem)], subMenuWidth)) - return true; - } - - return false; + TGUI_ASSERT(m_visibleMenu >= 0, "MenuBar::deselectDeepestItem can only be called when a menu is open"); + MenuWidgetBase::deselectDeepestItem(&m_menus[static_cast(m_visibleMenu)]); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1264,26 +660,15 @@ namespace tgui if (FloatRect{0, 0, getSize().x, getSize().y}.contains(pos)) return false; - Vector2f menuPos{0, 0}; const auto visibleMenuIdx = static_cast(m_visibleMenu); - for (std::size_t i = 0; i < visibleMenuIdx; ++i) - menuPos.x += m_menus[i].text.getSize().x + (2 * m_distanceToSideCached); - - if (m_invertedMenuDirection) - menuPos.y -= calculateOpenMenuHeight(m_menus[visibleMenuIdx].menuItems); - else - menuPos.y += getSize().y; + return MenuWidgetBase::isMouseOnOpenMenu(pos, m_menus[visibleMenuIdx], calculateMenuOffset(visibleMenuIdx)); + } - // The menu is moved to the left if it otherwise falls off the screen - bool openSubMenuToRight = true; - const float menuWidth = calculateMenuWidth(m_menus[visibleMenuIdx]); - if (getParent() && (menuPos.x + menuWidth > getParent()->getInnerSize().x)) - { - menuPos.x = std::max(0.f, getParent()->getInnerSize().x - menuWidth); - openSubMenuToRight = false; - } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - return isMouseOnTopOfMenu(menuPos, pos, openSubMenuToRight, m_menus[visibleMenuIdx], menuWidth); + float MenuBar::getDefaultMenuItemHeight() const + { + return getSize().y; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1296,23 +681,7 @@ namespace tgui const auto visibleMenuIdx = static_cast(m_visibleMenu); - auto* menu = &m_menus[visibleMenuIdx]; - std::vector hierarchy; - hierarchy.push_back(m_menus[visibleMenuIdx].text.getString()); - while (menu->selectedMenuItem >= 0) - { - auto& menuItem = menu->menuItems[static_cast(menu->selectedMenuItem)]; - hierarchy.push_back(menuItem.text.getString()); - if (menuItem.menuItems.empty()) - { - onMenuItemClick.emit(this, menuItem.text.getString(), hierarchy); - break; - } - - menu = &menuItem; - } - - closeMenu(); + MenuWidgetBase::leftMouseReleasedOnMenu(&m_menus[visibleMenuIdx]); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1322,85 +691,7 @@ namespace tgui TGUI_ASSERT(m_visibleMenu >= 0, "MenuBar::mouseMovedOnMenu can only be called when a menu is open"); const auto visibleMenuIdx = static_cast(m_visibleMenu); - Vector2f menuPos{0, 0}; - for (std::size_t i = 0; i < visibleMenuIdx; ++i) - menuPos.x += m_menus[i].text.getSize().x + (2 * m_distanceToSideCached); - - if (m_invertedMenuDirection) - menuPos.y -= calculateOpenMenuHeight(m_menus[visibleMenuIdx].menuItems); - else - menuPos.y += getSize().y; - - // The menu is moved to the left if it otherwise falls off the screen - bool openSubMenuToRight = true; - const float menuWidth = calculateMenuWidth(m_menus[visibleMenuIdx]); - if (getParent() && (menuPos.x + menuWidth > getParent()->getInnerSize().x)) - { - menuPos.x = std::max(0.f, getParent()->getInnerSize().x - menuWidth); - openSubMenuToRight = false; - } - - Menu* menuBelowMouse; - std::size_t menuItemIndexBelowMouse; - if (findMenuItemBelowMouse(menuPos, pos, openSubMenuToRight, m_menus[visibleMenuIdx], menuWidth, &menuBelowMouse, &menuItemIndexBelowMouse)) - { - // Check if the mouse is on a different item than before - auto& menu = *menuBelowMouse; - if (static_cast(menuItemIndexBelowMouse) != menu.selectedMenuItem) - { - // If another of the menu items is selected then unselect it - closeSubMenus(menu.menuItems, menu.selectedMenuItem); - - // Mark the item below the mouse as selected - auto& menuItem = menu.menuItems[menuItemIndexBelowMouse]; - if (menuItem.enabled && !isSeparator(menuItem)) - { - updateMenuTextColor(menu.menuItems[menuItemIndexBelowMouse], true); - menu.selectedMenuItem = static_cast(menuItemIndexBelowMouse); - } - } - else // We already selected this item - { - // If the selected item has a submenu then unselect its item - closeSubMenus(menu.menuItems[menuItemIndexBelowMouse].menuItems, menu.menuItems[menuItemIndexBelowMouse].selectedMenuItem); - } - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - bool MenuBar::findMenuItemBelowMouse(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, Menu& menu, float menuWidth, Menu** resultMenu, std::size_t* resultSelectedMenuItem) - { - // Loop over the open submenus and make sure to handle them first as menus can overlap - if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) - { - const float subMenuWidth = calculateMenuWidth(menu.menuItems[static_cast(menu.selectedMenuItem)]); - const Vector2f offset = calculateSubmenuOffset(menu, menuPos.x, menuWidth, subMenuWidth, openSubMenuToRight); - if (findMenuItemBelowMouse(menuPos + offset, mousePos, openSubMenuToRight, menu.menuItems[static_cast(menu.selectedMenuItem)], subMenuWidth, resultMenu, resultSelectedMenuItem)) - return true; - } - - // Check if the mouse is on top of the menu - if (!menu.menuItems.empty() && FloatRect{menuPos.x, menuPos.y, menuWidth, calculateOpenMenuHeight(menu.menuItems)}.contains(mousePos)) - { - std::size_t selectedItem = menu.menuItems.size() - 1; - float topPos = menuPos.y; - for (std::size_t i = 0; i < menu.menuItems.size(); ++i) - { - topPos += getMenuItemHeight(menu.menuItems[i]); - if (topPos > mousePos.y) - { - selectedItem = i; - break; - } - } - - *resultMenu = &menu; - *resultSelectedMenuItem = selectedItem; - return true; - } - - return false; + MenuWidgetBase::mouseMovedOnMenu(pos, m_menus[visibleMenuIdx], calculateMenuOffset(visibleMenuIdx)); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1454,256 +745,11 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void MenuBar::drawMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, float menuWidth, float globalLeftPos, bool openSubMenuToRight) const - { - if (menu.menuItems.empty()) - return; - - Transform oldTransform = states.transform; - - // Draw the backgrounds - Sprite backgroundSprite = m_spriteItemBackground; - if ((menu.selectedMenuItem < 0) && !backgroundSprite.isSet() && !m_selectedBackgroundColorCached.isSet()) - { - target.drawFilledRect(states, {menuWidth, calculateOpenMenuHeight(menu.menuItems)}, Color::applyOpacity(m_backgroundColorCached, m_opacityCached)); - } - else // We can't draw the entire menu with a singe draw call - { - for (std::size_t j = 0; j < menu.menuItems.size(); ++j) - { - const float menuItemHeight = getMenuItemHeight(menu.menuItems[j]); - const bool isMenuItemSelected = (menu.selectedMenuItem == static_cast(j)); - if (backgroundSprite.isSet()) - { - if (isMenuItemSelected && m_spriteSelectedItemBackground.isSet()) - { - Sprite selectedBackgroundSprite = m_spriteSelectedItemBackground; - selectedBackgroundSprite.setSize({menuWidth, menuItemHeight}); - target.drawSprite(states, selectedBackgroundSprite); - } - else // Not selected or no different texture for selected menu - { - backgroundSprite.setSize({menuWidth, menuItemHeight}); - target.drawSprite(states, backgroundSprite); - } - } - else // No textures where loaded - { - if (isMenuItemSelected && m_selectedBackgroundColorCached.isSet()) - target.drawFilledRect(states, {menuWidth, menuItemHeight}, Color::applyOpacity(m_selectedBackgroundColorCached, m_opacityCached)); - else - target.drawFilledRect(states, {menuWidth, menuItemHeight}, Color::applyOpacity(m_backgroundColorCached, m_opacityCached)); - } - - states.transform.translate({0, menuItemHeight}); - } - - states.transform = oldTransform; - } - - // Draw the texts (and arrows when there are submenus) - bool menuContainsSeparators = false; - states.transform.translate({m_distanceToSideCached, (getSize().y - menu.text.getSize().y) / 2.f}); - for (std::size_t j = 0; j < menu.menuItems.size(); ++j) - { - if (isSeparator(menu.menuItems[j])) - { - menuContainsSeparators = true; - states.transform.translate({0, getMenuItemHeight(menu.menuItems[j])}); - continue; - } - - target.drawText(states, menu.menuItems[j].text); - - // Draw an arrow next to the text if there is a submenu - if (!menu.menuItems[j].menuItems.empty()) - { - Transform textTransform = states.transform; - const float arrowHeight = getSize().y / 2.f; - const float arrowWidth = arrowHeight / 2.f; - states.transform.translate({menuWidth - 2*m_distanceToSideCached - arrowWidth, // 2x m_distanceToSideCached because we already translated once - (menu.menuItems[j].text.getSize().y - arrowHeight) / 2.f}); - - Vertex::Color arrowVertexColor; - if ((!m_enabled || !menu.menuItems[j].enabled) && m_textColorDisabledCached.isSet()) - arrowVertexColor = Vertex::Color(Color::applyOpacity(m_textColorDisabledCached, m_opacityCached)); - else if ((menu.selectedMenuItem == static_cast(j)) && m_selectedTextColorCached.isSet()) - arrowVertexColor = Vertex::Color(Color::applyOpacity(m_selectedTextColorCached, m_opacityCached)); - else - arrowVertexColor = Vertex::Color(Color::applyOpacity(m_textColorCached, m_opacityCached)); - - target.drawTriangle(states, - {{0, 0}, arrowVertexColor}, - {{arrowWidth, arrowHeight / 2.f}, arrowVertexColor}, - {{0, arrowHeight}, arrowVertexColor} - ); - - states.transform = textTransform; - } - - states.transform.translate({0, getSize().y}); - } - - if (menuContainsSeparators) - { - states.transform = oldTransform; - states.transform.translate({m_separatorSidePaddingCached, m_separatorVerticalPaddingCached}); - for (const auto& menuItem : menu.menuItems) - { - if (isSeparator(menuItem)) - target.drawFilledRect(states, {menuWidth - 2*m_separatorSidePaddingCached, m_separatorThicknessCached}, m_separatorColorCached); - - states.transform.translate({0, getMenuItemHeight(menuItem)}); - } - } - - // Draw the submenu if one is opened - if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) - { - const auto selectedMenuItemIdx = static_cast(menu.selectedMenuItem); - states.transform = oldTransform; - - // If there isn't enough room on the right side then open the menu to the left if it has more room - const float subMenuWidth = calculateMenuWidth(menu.menuItems[selectedMenuItemIdx]); - - float leftOffset; - if (openSubMenuToRight) - { - leftOffset = menuWidth; - if (getParent() && (globalLeftPos + leftOffset + subMenuWidth > getParent()->getInnerSize().x)) - { - if (globalLeftPos + leftOffset + subMenuWidth - getParent()->getInnerSize().x < globalLeftPos) - { - leftOffset = -subMenuWidth; - openSubMenuToRight = false; - } - } - } - else // Submenu opens to the left side - { - leftOffset = -subMenuWidth; - if (getParent() && (globalLeftPos < subMenuWidth)) - { - if (getParent()->getInnerSize().x - menuWidth - globalLeftPos > globalLeftPos) - { - leftOffset = menuWidth; - openSubMenuToRight = true; - } - } - } - - float topOffset = 0; - for (std::size_t i = 0; i < selectedMenuItemIdx; ++i) - topOffset += getMenuItemHeight(menu.menuItems[i]); - - if (m_invertedMenuDirection) - topOffset -= calculateOpenMenuHeight(menu.menuItems[selectedMenuItemIdx].menuItems) - getSize().y; - - states.transform.translate({leftOffset, topOffset}); - drawMenu(target, states, menu.menuItems[selectedMenuItemIdx], subMenuWidth, globalLeftPos + leftOffset, openSubMenuToRight); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - Widget::Ptr MenuBar::clone() const { return std::make_shared(*this); } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - MenuBarMenuPlaceholder::MenuBarMenuPlaceholder(MenuBar* menuBar) : - Widget{"MenuBarMenuPlaceholder", true}, - m_menuBar{menuBar} - { - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - Vector2f MenuBarMenuPlaceholder::getFullSize() const - { - if (m_parent) - return m_parent->getInnerSize() - getPosition(); - else - return {0, 0}; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - Vector2f MenuBarMenuPlaceholder::getWidgetOffset() const - { - return -getPosition(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - bool MenuBarMenuPlaceholder::isMouseOnWidget(Vector2f) const - { - return true; // Absorb all mouse events until the menu is closed - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBarMenuPlaceholder::leftMouseButtonNoLongerDown() - { - m_menuBar->leftMouseReleasedOnMenu(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBarMenuPlaceholder::mouseMoved(Vector2f pos) - { - bool mouseOnMenuBar = false; - if (m_menuBar->isMouseOnOpenMenu(pos - getPosition())) - { - m_mouseHover = true; - m_menuBar->mouseMovedOnMenu(pos - getPosition()); - } - else - { - if (m_mouseHover) - { - // Deselect the selected item of the deepest submenu - m_menuBar->deselectBottomItem(); - m_mouseHover = false; - } - - if (m_menuBar->getParent()) - { - const Vector2f menuBarMousePos = pos - m_menuBar->getAbsolutePosition() + m_menuBar->getPosition(); - if (m_menuBar->isMouseOnWidget(menuBarMousePos)) - { - mouseOnMenuBar = true; - m_mouseWasOnMenuBar = true; - m_menuBar->mouseMoved(menuBarMousePos); - } - } - } - - if (!mouseOnMenuBar && m_mouseWasOnMenuBar) - { - m_mouseWasOnMenuBar = false; - m_menuBar->mouseNoLongerOnWidget(); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void MenuBarMenuPlaceholder::draw(BackendRenderTarget& target, RenderStates states) const - { - m_menuBar->drawOpenMenu(target, states); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - Widget::Ptr MenuBarMenuPlaceholder::clone() const - { - // This function should never be called - return nullptr; - } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } diff --git a/src/Widgets/MenuWidgetBase.cpp b/src/Widgets/MenuWidgetBase.cpp new file mode 100644 index 000000000..c2e3ccd72 --- /dev/null +++ b/src/Widgets/MenuWidgetBase.cpp @@ -0,0 +1,1057 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#if !TGUI_EXPERIMENTAL_USE_STD_MODULE + #include +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace tgui +{ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase::MenuWidgetBase(const char* typeName, bool initRenderer) : + Widget{typeName, initRenderer}, + m_openMenuPlaceholder(std::make_shared(this)), + m_distanceToSideCached(std::round(Text::getLineHeight(m_fontCached, getGlobalTextSize()) * 0.4f)) + { + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase::MenuWidgetBase(const MenuWidgetBase& other) : + Widget {other}, + m_openMenuPlaceholder {std::make_shared(this)}, + m_minimumMenuWidth {other.m_minimumMenuWidth}, + m_spriteItemBackground {other.m_spriteItemBackground}, + m_spriteSelectedItemBackground {other.m_spriteSelectedItemBackground}, + m_backgroundColorCached {other.m_backgroundColorCached}, + m_selectedBackgroundColorCached{other.m_selectedBackgroundColorCached}, + m_textColorCached {other.m_textColorCached}, + m_selectedTextColorCached {other.m_selectedTextColorCached}, + m_textColorDisabledCached {other.m_textColorDisabledCached}, + m_distanceToSideCached {other.m_distanceToSideCached}, + m_invertedMenuDirection {other.m_invertedMenuDirection} + { + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase::MenuWidgetBase(MenuWidgetBase&& other) noexcept : + Widget {std::move(other)}, + m_openMenuPlaceholder {std::make_shared(this)}, + m_minimumMenuWidth {std::move(other.m_minimumMenuWidth)}, + m_spriteItemBackground {std::move(other.m_spriteItemBackground)}, + m_spriteSelectedItemBackground {std::move(other.m_spriteSelectedItemBackground)}, + m_backgroundColorCached {std::move(other.m_backgroundColorCached)}, + m_selectedBackgroundColorCached{std::move(other.m_selectedBackgroundColorCached)}, + m_textColorCached {std::move(other.m_textColorCached)}, + m_selectedTextColorCached {std::move(other.m_selectedTextColorCached)}, + m_textColorDisabledCached {std::move(other.m_textColorDisabledCached)}, + m_distanceToSideCached {std::move(other.m_distanceToSideCached)}, + m_invertedMenuDirection {std::move(other.m_invertedMenuDirection)} + { + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase& MenuWidgetBase::operator=(const MenuWidgetBase& other) + { + // Make sure it is not the same widget + if (this != &other) + { + Widget::operator=(other); + m_openMenuPlaceholder = other.m_openMenuPlaceholder; + m_minimumMenuWidth = other.m_minimumMenuWidth; + m_spriteItemBackground = other.m_spriteItemBackground; + m_spriteSelectedItemBackground = other.m_spriteSelectedItemBackground; + m_backgroundColorCached = other.m_backgroundColorCached; + m_selectedBackgroundColorCached = other.m_selectedBackgroundColorCached; + m_textColorCached = other.m_textColorCached; + m_selectedTextColorCached = other.m_selectedTextColorCached; + m_textColorDisabledCached = other.m_textColorDisabledCached; + m_distanceToSideCached = other.m_distanceToSideCached; + m_invertedMenuDirection = other.m_invertedMenuDirection; + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase& MenuWidgetBase::operator=(MenuWidgetBase&& other) noexcept + { + if (this != &other) + { + m_openMenuPlaceholder = std::move(other.m_openMenuPlaceholder); + m_minimumMenuWidth = std::move(other.m_minimumMenuWidth); + m_spriteItemBackground = std::move(other.m_spriteItemBackground); + m_spriteSelectedItemBackground = std::move(other.m_spriteSelectedItemBackground); + m_backgroundColorCached = std::move(other.m_backgroundColorCached); + m_selectedBackgroundColorCached = std::move(other.m_selectedBackgroundColorCached); + m_textColorCached = std::move(other.m_textColorCached); + m_selectedTextColorCached = std::move(other.m_selectedTextColorCached); + m_textColorDisabledCached = std::move(other.m_textColorDisabledCached); + m_distanceToSideCached = std::move(other.m_distanceToSideCached); + m_invertedMenuDirection = std::move(other.m_invertedMenuDirection); + Widget::operator=(std::move(other)); + } + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBaseRenderer* MenuWidgetBase::getSharedRenderer() + { + return aurora::downcast(Widget::getSharedRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + const MenuWidgetBaseRenderer* MenuWidgetBase::getSharedRenderer() const + { + return aurora::downcast(Widget::getSharedRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBaseRenderer* MenuWidgetBase::getRenderer() + { + return aurora::downcast(Widget::getRenderer()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Signal& MenuWidgetBase::getSignal(String signalName) + { + if (signalName == onMenuItemClick.getName()) + return onMenuItemClick; + else + return Widget::getSignal(std::move(signalName)); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::rendererChanged(const String& property) + { + if (property == U"TextureItemBackground") + { + m_spriteItemBackground.setTexture(getSharedRenderer()->getTextureItemBackground()); + } + else if (property == U"TextureSelectedItemBackground") + { + m_spriteSelectedItemBackground.setTexture(getSharedRenderer()->getTextureSelectedItemBackground()); + } + else if (property == U"BackgroundColor") + { + m_backgroundColorCached = getSharedRenderer()->getBackgroundColor(); + } + else if (property == U"SelectedBackgroundColor") + { + m_selectedBackgroundColorCached = getSharedRenderer()->getSelectedBackgroundColor(); + } + else if (property == U"DistanceToSide") + { + m_distanceToSideCached = getSharedRenderer()->getDistanceToSide(); + } + else if (property == U"SeparatorColor") + { + m_separatorColorCached = getSharedRenderer()->getSeparatorColor(); + } + else if (property == U"SeparatorThickness") + { + m_separatorThicknessCached = getSharedRenderer()->getSeparatorThickness(); + } + else if (property == U"SeparatorVerticalPadding") + { + m_separatorVerticalPaddingCached = getSharedRenderer()->getSeparatorVerticalPadding(); + } + else if (property == U"SeparatorSidePadding") + { + m_separatorSidePaddingCached = getSharedRenderer()->getSeparatorSidePadding(); + } + else + Widget::rendererChanged(property); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::drawOpenMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, Vector2f menuOffset) const + { + // Move the menu to the left if it otherwise falls off the screen + bool openSubMenuToRight = true; + const float menuWidth = calculateMenuWidth(menu); + if (getParent() && (getPosition().x + menuOffset.x + menuWidth > getParent()->getInnerSize().x)) + { + menuOffset.x = std::max(0.f, getParent()->getInnerSize().x - menuWidth); + openSubMenuToRight = false; + } + + states.transform.translate(menuOffset); + drawMenu(target, states, menu, menuWidth, getPosition().x + menuOffset.x, openSubMenuToRight); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::createMenu(std::vector& menus, const String& text) + { + Menu newMenu; + newMenu.text.setFont(m_fontCached); + newMenu.text.setColor(m_textColorCached); + newMenu.text.setOpacity(m_opacityCached); + newMenu.text.setCharacterSize(m_textSizeCached); + newMenu.text.setString(text); + menus.push_back(std::move(newMenu)); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase::Menu* MenuWidgetBase::findMenuItemParent(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus, bool createParents) + { + TGUI_ASSERT(hierarchy.size() >= 2, "Hierarchy needs at least 2 elements in MenuWidgetBase::findMenuItemParent!"); + + for (auto& menu : menus) + { + if (menu.text.getString() != hierarchy[parentIndex]) + continue; + + if (parentIndex + 2 == hierarchy.size()) + return &menu; + else + return findMenuItemParent(hierarchy, parentIndex + 1, menu.menuItems, createParents); + } + + if (createParents) + { + createMenu(menus, hierarchy[parentIndex]); + if (parentIndex + 2 == hierarchy.size()) + return &menus.back(); + else + return findMenuItemParent(hierarchy, parentIndex + 1, menus.back().menuItems, createParents); + } + + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + const MenuWidgetBase::Menu* MenuWidgetBase::findMenuItemParent(const std::vector& hierarchy, unsigned int parentIndex, const std::vector& menus) const + { + TGUI_ASSERT(hierarchy.size() >= 2, "Hierarchy needs at least 2 elements in MenuWidgetBase::findMenuItemParent!"); + + for (auto& menu : menus) + { + if (menu.text.getString() != hierarchy[parentIndex]) + continue; + + if (parentIndex + 2 == hierarchy.size()) + return &menu; + else + return findMenuItemParent(hierarchy, parentIndex + 1, menu.menuItems); + } + + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + MenuWidgetBase::Menu* MenuWidgetBase::findMenuItem(const std::vector& hierarchy, std::vector& menus) + { + if (hierarchy.empty()) + return nullptr; + + std::vector* menuItems; + if (hierarchy.size() == 1) + menuItems = &menus; + else + { + auto* menu = findMenuItemParent(hierarchy, 0, menus, false); + if (!menu) + return nullptr; + + menuItems = &menu->menuItems; + } + + for (auto& menuItem : *menuItems) + { + if (menuItem.text.getString() != hierarchy.back()) + continue; + + return &menuItem; + } + + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + const MenuWidgetBase::Menu* MenuWidgetBase::findMenuItem(const std::vector& hierarchy, const std::vector& menus) const + { + if (hierarchy.empty()) + return nullptr; + + const std::vector* menuItems; + if (hierarchy.size() == 1) + menuItems = &menus; + else + { + const auto* menu = findMenuItemParent(hierarchy, 0, menus); + if (!menu) + return nullptr; + + menuItems = &menu->menuItems; + } + + for (auto& menuItem : *menuItems) + { + if (menuItem.text.getString() != hierarchy.back()) + continue; + + return &menuItem; + } + + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::loadMenus(const std::unique_ptr& node, std::vector& menus) + { + for (const auto& childNode : node->children) + { + if (childNode->name != U"Menu") + continue; + + if (!childNode->propertyValuePairs[U"Text"]) + throw Exception{U"Failed to parse 'Menu' property, expected a nested 'Text' propery"}; + + const String menuText = Deserializer::deserialize(ObjectConverter::Type::String, childNode->propertyValuePairs[U"Text"]->value).getString(); + createMenu(menus, menuText); + + if (childNode->propertyValuePairs[U"Enabled"]) + menus.back().enabled = Deserializer::deserialize(ObjectConverter::Type::Bool, childNode->propertyValuePairs[U"Enabled"]->value).getBool(); + + // Recursively handle the menu nodes + if (!childNode->children.empty()) + loadMenus(childNode, menus.back().menuItems); + + // Menu items can also be stored in an string array in the 'Items' property instead of as a nested Menu section + if (childNode->propertyValuePairs[U"Items"]) + { + if (!childNode->propertyValuePairs[U"Items"]->listNode) + throw Exception{U"Failed to parse 'Items' property inside 'Menu' property, expected a list as value"}; + + for (std::size_t i = 0; i < childNode->propertyValuePairs[U"Items"]->valueList.size(); ++i) + { + const String menuItemText = Deserializer::deserialize(ObjectConverter::Type::String, childNode->propertyValuePairs[U"Items"]->valueList[i]).getString(); + createMenu(menus.back().menuItems, menuItemText); + } + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::closeSubMenus(std::vector& menus, int& selectedMenu) + { + if (selectedMenu < 0) + return; + + const auto selectedMenuIdx = static_cast(selectedMenu); + closeSubMenus(menus[selectedMenuIdx].menuItems, menus[selectedMenuIdx].selectedMenuItem); + + updateMenuTextColor(menus[selectedMenuIdx], false); + selectedMenu = -1; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::deselectDeepestItem(Menu* menu) + { + while (menu->selectedMenuItem >= 0) + { + auto& menuItem = menu->menuItems[static_cast(menu->selectedMenuItem)]; + if (menuItem.menuItems.empty()) + { + closeSubMenus(menu->menuItems, menu->selectedMenuItem); + break; + } + + menu = &menuItem; + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::updateMenuTextColor(Menu& menu, bool selected) + { + if ((!m_enabled || !menu.enabled) && m_textColorDisabledCached.isSet()) + menu.text.setColor(m_textColorDisabledCached); + else if (selected && m_selectedTextColorCached.isSet()) + menu.text.setColor(m_selectedTextColorCached); + else + menu.text.setColor(m_textColorCached); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::updateTextColors(std::vector& menus, int selectedMenu) + { + for (std::size_t i = 0; i < menus.size(); ++i) + { + updateMenuTextColor(menus[i], (selectedMenu == static_cast(i))); + updateTextColors(menus[i].menuItems, menus[i].selectedMenuItem); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::updateTextOpacity(std::vector& menus) + { + for (auto& menu : menus) + { + menu.text.setOpacity(m_opacityCached); + updateTextOpacity(menu.menuItems); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::updateTextFont(std::vector& menus) + { + for (auto& menu : menus) + { + menu.text.setFont(m_fontCached); + updateTextFont(menu.menuItems); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float MenuWidgetBase::calculateMenuWidth(const Menu& menu) const + { + float maxWidth = m_minimumMenuWidth; + const float arrowSpace = (getDefaultMenuItemHeight() / 4.f) + m_distanceToSideCached; + for (const auto& item : menu.menuItems) + { + float width = item.text.getSize().x + (2.f * m_distanceToSideCached); + + // Reserve space for an arrow if there are submenus + if (!item.menuItems.empty()) + width += arrowSpace; + + if (width > maxWidth) + maxWidth = width; + } + + return maxWidth; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float MenuWidgetBase::getMenuItemHeight(const Menu& menuItem) const + { + if (isSeparator(menuItem)) + return m_separatorThicknessCached + 2*m_separatorVerticalPaddingCached; + else + return getDefaultMenuItemHeight(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + float MenuWidgetBase::calculateOpenMenuHeight(const std::vector& menuItems) const + { + float height = 0; + for (const auto& item : menuItems) + height += getMenuItemHeight(item); + + return height; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Vector2f MenuWidgetBase::calculateSubmenuOffset(const Menu& menu, float globalLeftPos, float menuWidth, float subMenuWidth, bool& openSubMenuToRight) const + { + TGUI_ASSERT(menu.selectedMenuItem >= 0, "MenuWidgetBase::calculateSubmenuOffset can only be called when the menu has an open submenu"); + const auto selectedMenuItemIdx = static_cast(menu.selectedMenuItem); + + float leftOffset; + if (openSubMenuToRight) + { + leftOffset = menuWidth; + if (getParent() && (globalLeftPos + leftOffset + subMenuWidth > getParent()->getInnerSize().x)) + { + if (globalLeftPos + leftOffset + subMenuWidth - getParent()->getInnerSize().x < globalLeftPos) + { + leftOffset = -subMenuWidth; + openSubMenuToRight = false; + } + } + } + else // Submenu opens to the left side + { + leftOffset = -subMenuWidth; + if (getParent() && (globalLeftPos < subMenuWidth)) + { + if (getParent()->getInnerSize().x - menuWidth - globalLeftPos > globalLeftPos) + { + leftOffset = menuWidth; + openSubMenuToRight = true; + } + } + } + + float topOffset = 0; + for (std::size_t i = 0; i < selectedMenuItemIdx; ++i) + topOffset += getMenuItemHeight(menu.menuItems[i]); + + if (m_invertedMenuDirection) + topOffset -= calculateOpenMenuHeight(menu.menuItems[selectedMenuItemIdx].menuItems) - getDefaultMenuItemHeight(); + + return {leftOffset, topOffset}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::isSeparator(const Menu& menuItem) + { + return menuItem.text.getString() == U"-"; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::removeMenuImpl(const std::vector& hierarchy, bool removeParentsWhenEmpty, unsigned int parentIndex, std::vector& menus) + { + TGUI_ASSERT(!hierarchy.empty(), "Hierarchy can't be empty in MenuWidgetBase::removeMenuImpl!"); + + for (auto it = menus.begin(); it != menus.end(); ++it) + { + if (it->text.getString() != hierarchy[parentIndex]) + continue; + + if (parentIndex + 1 == hierarchy.size()) + { + menus.erase(it); + return true; + } + else + { + // Return false if some menu in the hierarchy couldn't be found + if (!removeMenuImpl(hierarchy, removeParentsWhenEmpty, parentIndex + 1, it->menuItems)) + return false; + + // If parents don't have to be removed as well then we are done + if (!removeParentsWhenEmpty) + return true; + + // Also delete the parent if empty + if (it->menuItems.empty()) + menus.erase(it); + + return true; + } + } + + // The hierarchy doesn't exist + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::removeSubMenusImpl(const std::vector& hierarchy, unsigned int parentIndex, std::vector& menus) + { + for (auto& menu : menus) + { + if (menu.text.getString() != hierarchy[parentIndex]) + continue; + + if (parentIndex + 1 == hierarchy.size()) + { + menu.menuItems.clear(); + return true; + } + else + return removeSubMenusImpl(hierarchy, parentIndex + 1, menu.menuItems); + } + + // The hierarchy doesn't exist + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::setTextSizeImpl(std::vector& menus, unsigned int textSize) + { + for (auto& menu : menus) + { + menu.text.setCharacterSize(textSize); + if (!menu.menuItems.empty()) + setTextSizeImpl(menu.menuItems, textSize); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + std::vector MenuWidgetBase::getMenusImpl(const std::vector& menus) + { + std::vector menuElements; + + for (const auto& menu : menus) + { + TGUI_EMPLACE_BACK(element, menuElements) + element.text = menu.text.getString(); + element.enabled = menu.enabled; + if (!menu.menuItems.empty()) + element.menuItems = getMenusImpl(menu.menuItems); + } + + return menuElements; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::saveMenus(const std::unique_ptr& parentNode, const std::vector& menus) + { + for (const auto& menu : menus) + { + auto menuNode = std::make_unique(); + menuNode->name = "Menu"; + + menuNode->propertyValuePairs[U"Text"] = std::make_unique(Serializer::serialize(menu.text.getString())); + if (!menu.enabled) + menuNode->propertyValuePairs[U"Enabled"] = std::make_unique(Serializer::serialize(menu.enabled)); + + if (!menu.menuItems.empty()) + { + // Save as nested 'Menu' sections only when needed, use the more compact string list when just storing the menu items + const bool recursionNeeded = std::any_of(menu.menuItems.begin(), menu.menuItems.end(), + [](const Menu& menuItem){ return !menuItem.enabled || !menuItem.menuItems.empty(); }); + if (recursionNeeded) + saveMenus(menuNode, menu.menuItems); + else + { + String itemList = "[" + Serializer::serialize(menu.menuItems[0].text.getString()); + for (std::size_t i = 1; i < menu.menuItems.size(); ++i) + itemList += ", " + Serializer::serialize(menu.menuItems[i].text.getString()); + itemList += "]"; + + menuNode->propertyValuePairs[U"Items"] = std::make_unique(itemList); + } + } + + parentNode->children.push_back(std::move(menuNode)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::isMouseOnTopOfMenu(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, const Menu& menu, float menuWidth) const + { + // Check if the mouse is on top of the menu + if (FloatRect{menuPos.x, menuPos.y, menuWidth, calculateOpenMenuHeight(menu.menuItems)}.contains(mousePos)) + return true; + + // Check if the mouse is on one of the submenus + if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) + { + const float subMenuWidth = calculateMenuWidth(menu.menuItems[static_cast(menu.selectedMenuItem)]); + const Vector2f offset = calculateSubmenuOffset(menu, menuPos.x, menuWidth, subMenuWidth, openSubMenuToRight); + if (isMouseOnTopOfMenu(menuPos + offset, mousePos, openSubMenuToRight, menu.menuItems[static_cast(menu.selectedMenuItem)], subMenuWidth)) + return true; + } + + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::isMouseOnOpenMenu(Vector2f pos, const Menu& menu, Vector2f menuOffset) const + { + // The menu is moved to the left if it otherwise falls off the screen + bool openSubMenuToRight = true; + const float menuWidth = calculateMenuWidth(menu); + if (getParent() && (menuOffset.x + menuWidth > getParent()->getInnerSize().x)) + { + menuOffset.x = std::max(0.f, getParent()->getInnerSize().x - menuWidth); + openSubMenuToRight = false; + } + + return isMouseOnTopOfMenu(menuOffset, pos, openSubMenuToRight, menu, menuWidth); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::leftMouseReleasedOnMenu(const Menu* menu) + { + bool emit = false; + std::vector hierarchy; + hierarchy.push_back(menu->text.getString()); + while (menu->selectedMenuItem >= 0) + { + auto& menuItem = menu->menuItems[static_cast(menu->selectedMenuItem)]; + hierarchy.push_back(menuItem.text.getString()); + if (menuItem.menuItems.empty()) + { + emit = true; + break; + } + + menu = &menuItem; + } + + closeMenu(); + if (emit) + emitMenuItemClick(hierarchy); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::mouseMovedOnMenu(Vector2f pos, Menu& menu, Vector2f menuOffset) + { + // The menu is moved to the left if it otherwise falls off the screen + bool openSubMenuToRight = true; + const float menuWidth = calculateMenuWidth(menu); + if (getParent() && (menuOffset.x + menuWidth > getParent()->getInnerSize().x)) + { + menuOffset.x = std::max(0.f, getParent()->getInnerSize().x - menuWidth); + openSubMenuToRight = false; + } + + Menu* menuBelowMouse; + std::size_t menuItemIndexBelowMouse; + if (findMenuItemBelowMouse(menuOffset, pos, openSubMenuToRight, menu, menuWidth, &menuBelowMouse, &menuItemIndexBelowMouse)) + { + // Check if the mouse is on a different item than before + if (static_cast(menuItemIndexBelowMouse) != menuBelowMouse->selectedMenuItem) + { + // If another of the menu items is selected then unselect it + closeSubMenus(menuBelowMouse->menuItems, menuBelowMouse->selectedMenuItem); + + // Mark the item below the mouse as selected + auto& menuItem = menuBelowMouse->menuItems[menuItemIndexBelowMouse]; + if (menuItem.enabled && !isSeparator(menuItem)) + { + updateMenuTextColor(menuBelowMouse->menuItems[menuItemIndexBelowMouse], true); + menuBelowMouse->selectedMenuItem = static_cast(menuItemIndexBelowMouse); + } + } + else // We already selected this item + { + // If the selected item has a submenu then unselect its item + closeSubMenus(menuBelowMouse->menuItems[menuItemIndexBelowMouse].menuItems, menuBelowMouse->menuItems[menuItemIndexBelowMouse].selectedMenuItem); + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool MenuWidgetBase::findMenuItemBelowMouse(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, Menu& menu, float menuWidth, Menu** resultMenu, std::size_t* resultSelectedMenuItem) + { + // Loop over the open submenus and make sure to handle them first as menus can overlap + if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) + { + const float subMenuWidth = calculateMenuWidth(menu.menuItems[static_cast(menu.selectedMenuItem)]); + const Vector2f offset = calculateSubmenuOffset(menu, menuPos.x, menuWidth, subMenuWidth, openSubMenuToRight); + if (findMenuItemBelowMouse(menuPos + offset, mousePos, openSubMenuToRight, menu.menuItems[static_cast(menu.selectedMenuItem)], subMenuWidth, resultMenu, resultSelectedMenuItem)) + return true; + } + + // Check if the mouse is on top of the menu + if (!menu.menuItems.empty() && FloatRect{menuPos.x, menuPos.y, menuWidth, calculateOpenMenuHeight(menu.menuItems)}.contains(mousePos)) + { + std::size_t selectedItem = menu.menuItems.size() - 1; + float topPos = menuPos.y; + for (std::size_t i = 0; i < menu.menuItems.size(); ++i) + { + topPos += getMenuItemHeight(menu.menuItems[i]); + if (topPos > mousePos.y) + { + selectedItem = i; + break; + } + } + + *resultMenu = &menu; + *resultSelectedMenuItem = selectedItem; + return true; + } + + return false; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void MenuWidgetBase::drawMenu(BackendRenderTarget& target, RenderStates states, const Menu& menu, float menuWidth, float globalLeftPos, bool openSubMenuToRight) const + { + if (menu.menuItems.empty()) + return; + + Transform oldTransform = states.transform; + + // Draw the backgrounds + Sprite backgroundSprite = m_spriteItemBackground; + if ((menu.selectedMenuItem < 0) && !backgroundSprite.isSet() && !m_selectedBackgroundColorCached.isSet()) + { + target.drawFilledRect(states, {menuWidth, calculateOpenMenuHeight(menu.menuItems)}, Color::applyOpacity(m_backgroundColorCached, m_opacityCached)); + } + else // We can't draw the entire menu with a singe draw call + { + for (std::size_t j = 0; j < menu.menuItems.size(); ++j) + { + const float menuItemHeight = getMenuItemHeight(menu.menuItems[j]); + const bool isMenuItemSelected = (menu.selectedMenuItem == static_cast(j)); + if (backgroundSprite.isSet()) + { + if (isMenuItemSelected && m_spriteSelectedItemBackground.isSet()) + { + Sprite selectedBackgroundSprite = m_spriteSelectedItemBackground; + selectedBackgroundSprite.setSize({menuWidth, menuItemHeight}); + target.drawSprite(states, selectedBackgroundSprite); + } + else // Not selected or no different texture for selected menu + { + backgroundSprite.setSize({menuWidth, menuItemHeight}); + target.drawSprite(states, backgroundSprite); + } + } + else // No textures where loaded + { + if (isMenuItemSelected && m_selectedBackgroundColorCached.isSet()) + target.drawFilledRect(states, {menuWidth, menuItemHeight}, Color::applyOpacity(m_selectedBackgroundColorCached, m_opacityCached)); + else + target.drawFilledRect(states, {menuWidth, menuItemHeight}, Color::applyOpacity(m_backgroundColorCached, m_opacityCached)); + } + + states.transform.translate({0, menuItemHeight}); + } + + states.transform = oldTransform; + } + + // Draw the texts (and arrows when there are submenus) + bool menuContainsSeparators = false; + const float itemHeight = getDefaultMenuItemHeight(); + states.transform.translate({m_distanceToSideCached, (itemHeight - menu.menuItems[0].text.getSize().y) / 2.f}); + for (std::size_t j = 0; j < menu.menuItems.size(); ++j) + { + if (isSeparator(menu.menuItems[j])) + { + menuContainsSeparators = true; + states.transform.translate({0, getMenuItemHeight(menu.menuItems[j])}); + continue; + } + + target.drawText(states, menu.menuItems[j].text); + + // Draw an arrow next to the text if there is a submenu + if (!menu.menuItems[j].menuItems.empty()) + { + Transform textTransform = states.transform; + const float arrowHeight = itemHeight / 2.f; + const float arrowWidth = arrowHeight / 2.f; + states.transform.translate({menuWidth - 2*m_distanceToSideCached - arrowWidth, // 2x m_distanceToSideCached because we already translated once + (menu.menuItems[j].text.getSize().y - arrowHeight) / 2.f}); + + Vertex::Color arrowVertexColor; + if ((!m_enabled || !menu.menuItems[j].enabled) && m_textColorDisabledCached.isSet()) + arrowVertexColor = Vertex::Color(Color::applyOpacity(m_textColorDisabledCached, m_opacityCached)); + else if ((menu.selectedMenuItem == static_cast(j)) && m_selectedTextColorCached.isSet()) + arrowVertexColor = Vertex::Color(Color::applyOpacity(m_selectedTextColorCached, m_opacityCached)); + else + arrowVertexColor = Vertex::Color(Color::applyOpacity(m_textColorCached, m_opacityCached)); + + target.drawTriangle(states, + {{0, 0}, arrowVertexColor}, + {{arrowWidth, arrowHeight / 2.f}, arrowVertexColor}, + {{0, arrowHeight}, arrowVertexColor} + ); + + states.transform = textTransform; + } + + states.transform.translate({0, itemHeight}); + } + + if (menuContainsSeparators) + { + states.transform = oldTransform; + states.transform.translate({m_separatorSidePaddingCached, m_separatorVerticalPaddingCached}); + for (const auto& menuItem : menu.menuItems) + { + if (isSeparator(menuItem)) + target.drawFilledRect(states, {menuWidth - 2*m_separatorSidePaddingCached, m_separatorThicknessCached}, m_separatorColorCached); + + states.transform.translate({0, getMenuItemHeight(menuItem)}); + } + } + + // Draw the submenu if one is opened + if ((menu.selectedMenuItem >= 0) && !menu.menuItems[static_cast(menu.selectedMenuItem)].menuItems.empty()) + { + const auto selectedMenuItemIdx = static_cast(menu.selectedMenuItem); + states.transform = oldTransform; + + // If there isn't enough room on the right side then open the menu to the left if it has more room + const float subMenuWidth = calculateMenuWidth(menu.menuItems[selectedMenuItemIdx]); + + float leftOffset; + if (openSubMenuToRight) + { + leftOffset = menuWidth; + if (getParent() && (globalLeftPos + leftOffset + subMenuWidth > getParent()->getInnerSize().x)) + { + if (globalLeftPos + leftOffset + subMenuWidth - getParent()->getInnerSize().x < globalLeftPos) + { + leftOffset = -subMenuWidth; + openSubMenuToRight = false; + } + } + } + else // Submenu opens to the left side + { + leftOffset = -subMenuWidth; + if (getParent() && (globalLeftPos < subMenuWidth)) + { + if (getParent()->getInnerSize().x - menuWidth - globalLeftPos > globalLeftPos) + { + leftOffset = menuWidth; + openSubMenuToRight = true; + } + } + } + + float topOffset = 0; + for (std::size_t i = 0; i < selectedMenuItemIdx; ++i) + topOffset += getMenuItemHeight(menu.menuItems[i]); + + if (m_invertedMenuDirection) + topOffset -= calculateOpenMenuHeight(menu.menuItems[selectedMenuItemIdx].menuItems) - itemHeight; + + states.transform.translate({leftOffset, topOffset}); + drawMenu(target, states, menu.menuItems[selectedMenuItemIdx], subMenuWidth, globalLeftPos + leftOffset, openSubMenuToRight); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + OpenMenuPlaceholder::OpenMenuPlaceholder(MenuWidgetBase* menuWidget) : + Widget{"OpenMenuPlaceholder", true}, + m_menuWidget{menuWidget} + { + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Vector2f OpenMenuPlaceholder::getFullSize() const + { + if (m_parent) + return m_parent->getInnerSize() - getPosition(); + else + return {0, 0}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Vector2f OpenMenuPlaceholder::getWidgetOffset() const + { + return -getPosition(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool OpenMenuPlaceholder::isMouseOnWidget(Vector2f) const + { + return true; // Absorb all mouse events until the menu is closed + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void OpenMenuPlaceholder::leftMouseButtonNoLongerDown() + { + m_menuWidget->leftMouseReleasedOnMenu(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void OpenMenuPlaceholder::mouseMoved(Vector2f pos) + { + bool mouseOnMenuWidget = false; + if (m_menuWidget->isMouseOnOpenMenu(pos - getPosition())) + { + m_mouseHover = true; + m_menuWidget->mouseMovedOnMenu(pos - getPosition()); + } + else + { + if (m_mouseHover) + { + // Deselect the selected item of the deepest submenu + m_menuWidget->deselectDeepestItem(); + m_mouseHover = false; + } + + if (m_menuWidget->getParent()) + { + const Vector2f menuWidgetMousePos = pos - m_menuWidget->getAbsolutePosition() + m_menuWidget->getPosition(); + if (m_menuWidget->isMouseOnWidget(menuWidgetMousePos)) + { + mouseOnMenuWidget = true; + m_mouseWasOnMenuWidget = true; + m_menuWidget->mouseMoved(menuWidgetMousePos); + } + } + } + + if (!mouseOnMenuWidget && m_mouseWasOnMenuWidget) + { + m_mouseWasOnMenuWidget = false; + m_menuWidget->mouseNoLongerOnWidget(); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void OpenMenuPlaceholder::draw(BackendRenderTarget& target, RenderStates states) const + { + m_menuWidget->drawOpenMenu(target, states); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Widget::Ptr OpenMenuPlaceholder::clone() const + { + // This function should never be called + return nullptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e5700a37a..6e15054ab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -66,6 +66,7 @@ set(TEST_SOURCES Widgets/ClickableWidget.cpp Widgets/ColorPicker.cpp Widgets/ComboBox.cpp + Widgets/ContextMenu.cpp Widgets/EditBox.cpp Widgets/EditBoxSlider.cpp Widgets/FileDialog.cpp diff --git a/tests/Widgets/ContextMenu.cpp b/tests/Widgets/ContextMenu.cpp new file mode 100644 index 000000000..4f066261a --- /dev/null +++ b/tests/Widgets/ContextMenu.cpp @@ -0,0 +1,448 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Tests.hpp" + +TEST_CASE("[ContextMenu]") +{ + tgui::ContextMenu::Ptr contextMenu = tgui::ContextMenu::create(); + contextMenu->getRenderer()->setFont("resources/DejaVuSans.ttf"); + + SECTION("Signals") + { + contextMenu->onMenuItemClick([](){}); + contextMenu->onMenuItemClick([](const tgui::String&){}); + contextMenu->onMenuItemClick([](const std::vector&){}); + + contextMenu->connectMenuItem("Save", [](){}); + contextMenu->connectMenuItem({"Help", "About", "Version"}, [](){}); + + REQUIRE_NOTHROW(tgui::Widget::Ptr(contextMenu)->getSignal("MenuItemClicked").connect([]{})); + } + + SECTION("WidgetType") + { + REQUIRE(contextMenu->getWidgetType() == "ContextMenu"); + } + + SECTION("Position and Size") + { + REQUIRE(contextMenu->addMenuItem({"Smilies", "Happy"})); + REQUIRE(contextMenu->addMenuItem({"Smilies", "Sad"})); + REQUIRE(contextMenu->addMenuItem({"Smilies", "Neither"})); + REQUIRE(contextMenu->addMenuItem({"Vehicles", "Parts", "Wheel"})); + REQUIRE(contextMenu->addMenuItem({"Vehicles", "Whole", "Truck"})); + REQUIRE(contextMenu->addMenuItem({"Vehicles", "Whole", "Car"})); + + contextMenu->setMinimumMenuWidth(300); + contextMenu->setItemHeight(20); + contextMenu->setPosition(40, 30); + contextMenu->setSize(150, 100); // Has no effect + + REQUIRE(contextMenu->getPosition() == tgui::Vector2f(40, 30)); + REQUIRE(contextMenu->getWidgetOffset() == tgui::Vector2f(0, 0)); + + // The position can be set when opening the menu + contextMenu->openMenu({80, 60}); + REQUIRE(contextMenu->getPosition() == tgui::Vector2f(80, 60)); + REQUIRE(contextMenu->getWidgetOffset() == tgui::Vector2f(0, 0)); + + // The context menu has no size. It's menu is an overlay that is a separate widget. + REQUIRE(contextMenu->getSize() == tgui::Vector2f(0, 0)); + REQUIRE(contextMenu->getFullSize() == contextMenu->getSize()); + } + + SECTION("Open / close") + { + contextMenu->addMenuItem("Load"); + contextMenu->addMenuItem("Save"); + + REQUIRE(!contextMenu->isMenuOpen()); + + contextMenu->openMenu(); + REQUIRE(contextMenu->isMenuOpen()); + + contextMenu->closeMenu(); + REQUIRE(!contextMenu->isMenuOpen()); + } + + SECTION("ItemHeight") + { + contextMenu->setItemHeight(25); + REQUIRE(contextMenu->getItemHeight() == 25); + } + + SECTION("MinimumMenuWidth") + { + contextMenu->setMinimumMenuWidth(250); + REQUIRE(contextMenu->getMinimumMenuWidth() == 250); + } + + SECTION("TextSize") + { + contextMenu->setTextSize(20); + REQUIRE(contextMenu->getTextSize() == 20); + } + + SECTION("Changing menu items") + { + contextMenu->addMenuItem("Cut"); + contextMenu->addMenuItem("Copy"); + contextMenu->addMenuItem("Paste"); + contextMenu->addMenuItem("-"); + contextMenu->addMenuItem({"Edit", "Undo"}); + contextMenu->addMenuItem({"Edit", "Redo"}); + contextMenu->addMenuItem({"Edit", "Delete"}); + + contextMenu->changeMenuItem({"Paste"}, "PASTE"); + contextMenu->changeMenuItem({"Edit", "Redo"}, "REDO"); + + REQUIRE(contextMenu->getMenuItems().size() == 5); + REQUIRE(contextMenu->getMenuItems()[0].text == "Cut"); + REQUIRE(contextMenu->getMenuItems()[0].menuItems.empty()); + REQUIRE(contextMenu->getMenuItems()[1].text == "Copy"); + REQUIRE(contextMenu->getMenuItems()[2].text == "PASTE"); + REQUIRE(contextMenu->getMenuItems()[3].text == "-"); + REQUIRE(contextMenu->getMenuItems()[4].text == "Edit"); + REQUIRE(contextMenu->getMenuItems()[4].menuItems.size() == 3); + REQUIRE(contextMenu->getMenuItems()[4].menuItems[0].text == "Undo"); + REQUIRE(contextMenu->getMenuItems()[4].menuItems[1].text == "REDO"); + REQUIRE(contextMenu->getMenuItems()[4].menuItems[2].text == "Delete"); + + contextMenu->removeMenuItem("Copy"); + contextMenu->removeMenuItem({"Edit", "Delete"}); + REQUIRE(contextMenu->getMenuItems().size() == 4); + REQUIRE(contextMenu->getMenuItems()[0].text == "Cut"); + REQUIRE(contextMenu->getMenuItems()[1].text == "PASTE"); + REQUIRE(contextMenu->getMenuItems()[2].text == "-"); + REQUIRE(contextMenu->getMenuItems()[3].text == "Edit"); + REQUIRE(contextMenu->getMenuItems()[3].menuItems.size() == 2); + REQUIRE(contextMenu->getMenuItems()[3].menuItems[0].text == "Undo"); + REQUIRE(contextMenu->getMenuItems()[3].menuItems[1].text == "REDO"); + + contextMenu->removeSubMenuItems({"Edit"}); + REQUIRE(contextMenu->getMenuItems().size() == 4); + REQUIRE(contextMenu->getMenuItems()[3].text == "Edit"); + REQUIRE(contextMenu->getMenuItems()[3].menuItems.empty()); + + contextMenu->removeAllMenuItems(); + REQUIRE(contextMenu->getMenuItems().empty()); + } + + SECTION("Menu items enabled / disabled") + { + contextMenu->addMenuItem("Copy"); + contextMenu->addMenuItem("Paste"); + contextMenu->addMenuItem({"Edit", "Undo"}); + contextMenu->addMenuItem({"Edit", "Redo"}); + + contextMenu->setMenuItemEnabled("Paste", false); + contextMenu->setMenuItemEnabled({"Edit", "Redo"}, false); + + REQUIRE(contextMenu->getMenuItemEnabled("Copy")); + REQUIRE(!contextMenu->getMenuItemEnabled("Paste")); + REQUIRE(contextMenu->getMenuItemEnabled({"Edit", "Undo"})); + REQUIRE(!contextMenu->getMenuItemEnabled({"Edit", "Redo"})); + } + + SECTION("Events / Signals") + { + contextMenu->addMenuItem("Copy"); + contextMenu->addMenuItem("Paste"); + contextMenu->addMenuItem({"Edit", "Undo"}); + contextMenu->addMenuItem({"Edit", "Redo"}); + contextMenu->setMinimumMenuWidth(150); + contextMenu->setItemHeight(20); + + unsigned int callbackCount = 0; + std::vector expectedHierarchy; + contextMenu->onMenuItemClick([&](const std::vector& hierarchy) { + ++callbackCount; + REQUIRE(expectedHierarchy == hierarchy); + }); + + // The context menu needs to be attached to a Gui object as it will create a new widget when the menu opens. + // All events also need to be send to the gui to determine to which widget the event goes. + globalGui->add(contextMenu); + auto simulateMouseMove = [](int x, int y){ + tgui::Event event; + event.type = tgui::Event::Type::MouseMoved; + event.mouseMove.x = x; + event.mouseMove.y = y; + globalGui->handleEvent(event); + }; + auto simulateLeftMouseClick = [](int x, int y){ + tgui::Event event; + event.type = tgui::Event::Type::MouseMoved; + event.mouseMove.x = x; + event.mouseMove.y = y; + globalGui->handleEvent(event); + + event.type = tgui::Event::Type::MouseButtonPressed; + event.mouseButton.button = tgui::Event::MouseButton::Left; + event.mouseButton.x = x; + event.mouseButton.y = y; + globalGui->handleEvent(event); + + event.type = tgui::Event::Type::MouseButtonReleased; + event.mouseButton.button = tgui::Event::MouseButton::Left; + event.mouseButton.x = x; + event.mouseButton.y = y; + globalGui->handleEvent(event); + }; + + contextMenu->openMenu({100, 50}); + contextMenu->closeMenu(); + + // The context menu isn't shown and thus won't react while the menu is closed + contextMenu->setPosition({100, 50}); + simulateLeftMouseClick(110, 60); + REQUIRE(callbackCount == 0); + + // Clicking on one of the menu items sends a callback and closes the menu + expectedHierarchy = {"Copy"}; + contextMenu->openMenu(); + REQUIRE(contextMenu->isMenuOpen()); + simulateLeftMouseClick(110, 60); + REQUIRE(callbackCount == 1); + REQUIRE(!contextMenu->isMenuOpen()); + + // The submenu isn't open if we don't hover on the parent item first + contextMenu->openMenu(); + simulateLeftMouseClick(260, 120); + REQUIRE(callbackCount == 1); + + // Clicking on one of the menu items in a submenu also sends a callback and closes the menu + expectedHierarchy = {"Edit", "Redo"}; + contextMenu->openMenu(); + simulateMouseMove(110, 100); // Hover on Edit to open the submenu + simulateLeftMouseClick(260, 120); + REQUIRE(callbackCount == 2); + REQUIRE(!contextMenu->isMenuOpen()); + + // The menu item no longer sends a callback when it is disabled + contextMenu->setMenuItemEnabled({"Edit", "Redo"}, false); + contextMenu->openMenu(); + simulateMouseMove(110, 100); // Hover on Edit to open the submenu + simulateLeftMouseClick(260, 120); + REQUIRE(callbackCount == 2); + + // Clicking beside the menu will close it + contextMenu->openMenu(); + simulateLeftMouseClick(251, 80); + REQUIRE(callbackCount == 2); + REQUIRE(!contextMenu->isMenuOpen()); + + // Adding a long item makes the menu wider, so clicking on the same spot again will now trigger a callback + expectedHierarchy = {"Paste"}; + contextMenu->addMenuItem("Some very long item that will make the context menu wider"); + contextMenu->openMenu(); + simulateLeftMouseClick(251, 80); + REQUIRE(callbackCount == 3); + + globalGui->removeAllWidgets(); + } + + testWidgetRenderer(contextMenu->getRenderer()); + SECTION("Renderer") + { + auto renderer = contextMenu->getRenderer(); + + SECTION("colored") + { + SECTION("set serialized property") + { + REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", "rgb(10, 20, 30)")); + REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColor", "rgb(40, 50, 60)")); + REQUIRE_NOTHROW(renderer->setProperty("TextColor", "rgb(70, 80, 90)")); + REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColor", "rgb(100, 110, 120)")); + REQUIRE_NOTHROW(renderer->setProperty("TextColorDisabled", "rgb(130, 140, 150)")); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorColor", "rgb(160, 170, 180)")); + REQUIRE_NOTHROW(renderer->setProperty("DistanceToSide", "2")); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorThickness", "3")); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorVerticalPadding", "4")); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorSidePadding", "5")); + } + + SECTION("set object property") + { + REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", tgui::Color{10, 20, 30})); + REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColor", tgui::Color{40, 50, 60})); + REQUIRE_NOTHROW(renderer->setProperty("TextColor", tgui::Color{70, 80, 90})); + REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColor", tgui::Color{100, 110, 120})); + REQUIRE_NOTHROW(renderer->setProperty("TextColorDisabled", tgui::Color{130, 140, 150})); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorColor", tgui::Color{160, 170, 180})); + REQUIRE_NOTHROW(renderer->setProperty("DistanceToSide", 2)); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorThickness", 3)); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorVerticalPadding", 4)); + REQUIRE_NOTHROW(renderer->setProperty("SeparatorSidePadding", 5)); + } + + SECTION("functions") + { + renderer->setBackgroundColor({10, 20, 30}); + renderer->setSelectedBackgroundColor({40, 50, 60}); + renderer->setTextColor({70, 80, 90}); + renderer->setSelectedTextColor({100, 110, 120}); + renderer->setTextColorDisabled({130, 140, 150}); + renderer->setSeparatorColor({160, 170, 180}); + renderer->setDistanceToSide(2); + renderer->setSeparatorThickness(3); + renderer->setSeparatorVerticalPadding(4); + renderer->setSeparatorSidePadding(5); + } + + REQUIRE(renderer->getProperty("BackgroundColor").getColor() == tgui::Color(10, 20, 30)); + REQUIRE(renderer->getProperty("SelectedBackgroundColor").getColor() == tgui::Color(40, 50, 60)); + REQUIRE(renderer->getProperty("TextColor").getColor() == tgui::Color(70, 80, 90)); + REQUIRE(renderer->getProperty("SelectedTextColor").getColor() == tgui::Color(100, 110, 120)); + REQUIRE(renderer->getProperty("TextColorDisabled").getColor() == tgui::Color(130, 140, 150)); + REQUIRE(renderer->getProperty("SeparatorColor").getColor() == tgui::Color(160, 170, 180)); + REQUIRE(renderer->getProperty("DistanceToSide").getNumber() == 2); + REQUIRE(renderer->getProperty("SeparatorThickness").getNumber() == 3); + REQUIRE(renderer->getProperty("SeparatorVerticalPadding").getNumber() == 4); + REQUIRE(renderer->getProperty("SeparatorSidePadding").getNumber() == 5); + } + + SECTION("textured") + { + tgui::Texture textureItemBackground("resources/Black.png", {115, 181, 8, 4}, {2, 0, 4, 2}); + tgui::Texture textureSelectedItemBackground("resources/Black.png", {115, 185, 8, 6}, {2, 2, 4, 2}); + + SECTION("set serialized property") + { + REQUIRE_NOTHROW(renderer->setProperty("TextureItemBackground", tgui::Serializer::serialize(textureItemBackground))); + REQUIRE_NOTHROW(renderer->setProperty("TextureSelectedItemBackground", tgui::Serializer::serialize(textureSelectedItemBackground))); + } + + SECTION("set object property") + { + REQUIRE_NOTHROW(renderer->setProperty("TextureItemBackground", textureItemBackground)); + REQUIRE_NOTHROW(renderer->setProperty("TextureSelectedItemBackground", textureSelectedItemBackground)); + } + + SECTION("functions") + { + renderer->setTextureItemBackground(textureItemBackground); + renderer->setTextureSelectedItemBackground(textureSelectedItemBackground); + } + + REQUIRE(renderer->getProperty("TextureItemBackground").getTexture().getData() != nullptr); + REQUIRE(renderer->getProperty("TextureSelectedItemBackground").getTexture().getData() != nullptr); + + REQUIRE(renderer->getTextureItemBackground().getData() == textureItemBackground.getData()); + REQUIRE(renderer->getTextureSelectedItemBackground().getData() == textureSelectedItemBackground.getData()); + } + } + + SECTION("Saving and loading from file") + { + contextMenu->addMenuItem("Copy"); + contextMenu->addMenuItem("Paste"); + contextMenu->addMenuItem({"Edit", "Undo"}); + contextMenu->addMenuItem({"Edit", "Redo"}); + contextMenu->setMenuItemEnabled({"Edit", "Redo"}, false); + + contextMenu->setMinimumMenuWidth(100); + contextMenu->setItemHeight(30); + contextMenu->setTextSize(25); + + testSavingWidget("ContextMenu", contextMenu); + } + + SECTION("Draw") + { + TEST_DRAW_INIT(140, 90, contextMenu) + + contextMenu->setEnabled(true); + contextMenu->setPosition(10, 5); + contextMenu->setTextSize(16); + contextMenu->setItemHeight(20); + contextMenu->setMinimumMenuWidth(60); + + contextMenu->addMenuItem("Copy"); + contextMenu->addMenuItem("Paste"); + contextMenu->addMenuItem({"Edit", "Undo"}); + contextMenu->addMenuItem({"Edit", "Redo"}); + + contextMenu->setMenuItemEnabled("Paste", false); + contextMenu->setMenuItemEnabled({"Edit", "Redo"}, false); + + tgui::ContextMenuRenderer renderer = tgui::RendererData::create(); + renderer.setTextColor(tgui::Color::Red); + renderer.setSelectedTextColor(tgui::Color::Blue); + renderer.setTextColorDisabled(tgui::Color::Black); + renderer.setBackgroundColor(tgui::Color::Green); + renderer.setSelectedBackgroundColor(tgui::Color::Yellow); + renderer.setDistanceToSide(3); + renderer.setOpacity(0.7f); + contextMenu->setRenderer(renderer.getData()); + + auto container = gui.getContainer(); + + SECTION("Closed") + { + TEST_DRAW("ContextMenu_Closed.png") + } + + contextMenu->openMenu(); + + SECTION("Colored") + { + TEST_DRAW("ContextMenu.png") + + tgui::Vector2f mousePos = {20, 35}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_HoverDisabled.png") + + mousePos = {20, 55}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_SubMenuOpen.png") + + mousePos = {80, 55}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_SubMenuItemHover.png") + } + + SECTION("Textured") + { + renderer.setTextureItemBackground("resources/Texture2.png"); + renderer.setTextureSelectedItemBackground("resources/Texture3.png"); + + TEST_DRAW("ContextMenu_Textured.png") + + tgui::Vector2f mousePos = {20, 35}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_HoverDisabled_Textured.png") + + mousePos = {20, 55}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_SubMenuOpen_Textured.png") + + mousePos = {80, 55}; + container->mouseMoved(mousePos); + TEST_DRAW("ContextMenu_SubMenuItemHover_Textured.png") + } + } +} diff --git a/tests/expected/ContextMenu.png b/tests/expected/ContextMenu.png new file mode 100644 index 0000000000000000000000000000000000000000..642b1f7e080288a27a992d53d6c3c7b6e7d925b4 GIT binary patch literal 2889 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 literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_Closed.png b/tests/expected/ContextMenu_Closed.png new file mode 100644 index 0000000000000000000000000000000000000000..2499cacc32b7da82cf49bb22781f0ebb3661d7fb GIT binary patch literal 645 zcmeAS@N?(olHy`uVBq!ia0vp^JwP1A!3HF=mhak` zh7$q_QoJiK3Mi`UG&_?a1!6911Tz!B!c7n5m=^cmyJ%u} z>xHZ@^A_$#kg27;KtnSVwzNq4GB3XS3TUE;bHWy0<5_v`x4{xXCYu|A*;dQZV^-xZ z{4-;5xd|_bdHDbavyGvMqvzWsx690)iUzY1Kt5`MoA2S2u*FNtw`+0eC7>(U0#$+i z!`7C>(X%bl?eg0UX`pAp%mYZw4g8H4-QH&?$>)CQ1NsZdl#);Z29Ij5+EI}Ad3(Y< zK^_4b&FpN*0&?=pGLT1*T@Ufdjdrk;C-x&;&ofB?id2)c9;#mlG3X(4ac)-!IOBN9`NRcG* zP0;`pF;Bp81ZFZftFVBavcv)u%Z*6B)Mx_-&D}{NObiF6F-6E29MuLUF9uInKbLh* G2~7aASOpaT literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_HoverDisabled.png b/tests/expected/ContextMenu_HoverDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..642b1f7e080288a27a992d53d6c3c7b6e7d925b4 GIT binary patch literal 2889 zcmZvedo+|=AIIm`V}^$a88nzMr8GSZMY#;=iBxAImqY0pmyBE*C8Qkl5V;IV?p;i0 zI=wFCOedm?)5yJ4E~!o~jS?ryrFfHu=bh7E?^^Hs$KLz9_HX_6+WYtWuDw1PoIN{K zmGzWyIGn1RtBZ$X6)J`w8BolJ|Me$`!>Opdxj5~M4+zSSc)RcnQiit)+SL&~)rxL) zBU2Kr*~v@bQg=h*48b8fVCFdsQhocTnv!zLMcVs297^*gr=>g!tJECshs0q5 zZjCCdlnm@3OE}|T$ruPO-NRUa56GVx&7MPtH+MDf=mEhtRbAcKeoIR^HBuR@s@bzQ z`KI01GJ4WdQrgzfAXwF)s~eDR3Gs3Lt$ua7)Z{pMs7&4{l{`8VUBjosbarg=xl=9D z+&YsVbvT6Z#=o~o7qe0BPCH}jms6?f9gf@QN*6mYa8zfB)u|E^TwF}fn19`Y z=_2E?uUMATiCkQj(~GdUaYthRMj*|8lQ<)_@Hf4`DDa3qu_>JX_TtJvJ~`G~3~<_; z`2*=1LZ=80Wm(>~P0RLqSdFqQE?S+gT#pbYREN|mhAz8W;@tHCpsuOB@6yB-#l>o= z)PPLkrV=0|nclM3uMT5fd=V5p|0tttSztzxPPh%k^F;A{3yEn@2aSSVs6-t0%~-qMnL31NmqmVY0_mQTW(M@M{^0D%5fTse;h z9<1lIL{|{4f90-o%09sHZ<(>V%8f`Ib!-X~Gb)&6~5wVAYk;NuyZjGW+ z#)U(y@{umod$Y(OXGXid9_-ZL|3;U(i;0ESSEl)`qaHBbGsu*QjM{~HKVwwiC876@ z*+)jfaaCnm7SOJp2x<9%Tf^xQJ}2co?UiSDy-GwrLH|lWjjCH+ZUJ4N2@J-W7B6IA z)EC6IP_~;1*+!zYlW$}j{A?*W2r+^Ox8ec*J@Rugp*DI*Ij7KUmW?*(c_8kU_S|=Z>e>8p~4pEDA7KE$?BK%)E z0v!J_Bgq0GyFrGh~dYMQ zP|+s2@DT{^lFqF)mwFw=93e=454w9f&V~_LdA12!ms}~tKq<>BnTcm=&~n*;?Z%zsKkW$gizg|>XoR-n_P1C z8M^7z7O|A_@fEI5<>GuW>8U^Z#D{j{F7F&taT#H2kdLl4hN7WUIA$V_nHNYK@Hgdda||6xj=1Y+p=(c%;Vg;L-A*^!^r`=E+E^+zGTD2%Wp zZn)2IpK|_MEQT=QjGWA{T~W*yRDD^Z1tasU8AqbKZkPF;?(wYGboPm4e4kws`gCFW z;U=7W{%;tSic-+M%X_9nytmtwXq4ydO+7apH|Lm^B&~&Z!MPqX%pN%o?8mhPQ-)Jq z8JZ@EnVd~E3n?9PVr{q}^Jnzd5ZLv;Y?q$&Nz88PZ7qpOpqt@_5a2-aHGi05tb`V(ocHxaR zLIL&@J8}EBHBIYq4K(@IvIoaR`F5p<;$*y!ru2p(DAh~TsL2xO4>v!M-d?u05h9-4 zEMi&^*FXexW?p|^wvnm9s1`%x%HBo2m^78O4LxOmO@QjNd_t-hc%iJ2aIo=yRgI(HvddJY^AeB#> zI_~wnNqdLqQ)wEm#kfI95bnzktreYoS7P(Qpo+lEPsplSu@S5vT9z+ho~?dIv-)=W zEs2;Z^Ur)fv%I#G-fAuCiHLc;;lm7EWE;@swl6vyW3}Upn5Rh9FI#F+gF8Euz2ZcN zRbrDFwZ`#Q-5@&|PxEP&>+}Y`y7JgVT5#N2dMwtk9fD@p;MXiej|tJO^w8enW6bgd z!lfQT)g!UDu6-%bRmCmSo!ZqMWF(A=JY}dkU+mRodtW5BWrt4va%R%=Zh1#LBwjEK zD0*1A=CJpPdh=Dgt(w>9WomZ*f{1newZG63vN9GLFtGmV(6UQIPax&AePqr>gndSH zsG#jrXjg%aB0@8#Tfd$+bztxutfzAfzv?!m&=o)J%AP=UlrqZTThpp<#ZheM47-kB ze-Ku59oAI&z;%x#zfw#YrM%M z{%V4Co>N_+wAF`in`pq_&0oQ%9kJ(6tY;}Y$TMMqHq-;XS;orn)QwgHNIb!%!gw<} zREog8Dos3vRY+DU_+RxK#K#wS>qx0mUV&Aq8eDa?+lqZpow|Vwd%pY!AOYCDxZ4VH zbw+A->g~=Hd-d@2s5kQ9-X94-S|C|?n+x}T;_3fmwtuAbzocY2+6_!RY_lSi!amFfN;}E26-I3WamqzQ?878A<*R=n5B^ literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_HoverDisabled_Textured.png b/tests/expected/ContextMenu_HoverDisabled_Textured.png new file mode 100644 index 0000000000000000000000000000000000000000..efac59d834164beded448ef570ebd243c6ea8a85 GIT binary patch literal 4199 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 RLGposaNK*)?x8I?;lHMqt=0el literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_SubMenuItemHover.png b/tests/expected/ContextMenu_SubMenuItemHover.png new file mode 100644 index 0000000000000000000000000000000000000000..a896d7904453f14e432c0cae437c4527f2742dbd GIT binary patch literal 4146 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 a0=PuFnY};cf&4E3;ktY8uG@}a;{O1nm2q$Y literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_SubMenuItemHover_Textured.png b/tests/expected/ContextMenu_SubMenuItemHover_Textured.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7c3263cb16fec7d1b6df2245e07c3151db2b8d GIT binary patch literal 6344 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 U&8dm44h72Y@Nw%WR-}ag16Q4;ng9R* literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_SubMenuOpen.png b/tests/expected/ContextMenu_SubMenuOpen.png new file mode 100644 index 0000000000000000000000000000000000000000..d69b51add4ebe411f2fc71648c7a2add4a953508 GIT binary patch literal 4154 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 literal 0 HcmV?d00001 diff --git a/tests/expected/ContextMenu_SubMenuOpen_Textured.png b/tests/expected/ContextMenu_SubMenuOpen_Textured.png new file mode 100644 index 0000000000000000000000000000000000000000..fb124f5d2df886d8183bb62cee162e9c115b2839 GIT binary patch literal 6346 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 RLGposaNK*)?x8I?;lHMqt=0el literal 0 HcmV?d00001 diff --git a/themes/BabyBlue.txt b/themes/BabyBlue.txt index 06dc43ede..5c3ecc9cc 100644 --- a/themes/BabyBlue.txt +++ b/themes/BabyBlue.txt @@ -53,6 +53,10 @@ ComboBox { Borders = (2, 2, 2, 2); } +ContextMenu { + DistanceToSide = 5; +} + EditBox { Texture = "BabyBlue.png" Part(103, 40, 72, 48) Middle(24, 0, 24, 48) Smooth; CaretColor = rgb(145, 180, 190); diff --git a/themes/Black.txt b/themes/Black.txt index 239f0e5f4..f6a39e69c 100644 --- a/themes/Black.txt +++ b/themes/Black.txt @@ -58,6 +58,12 @@ ComboBox { Padding = (3, 3, 3, 3); } +ContextMenu { + TextureItemBackground = "Black.png" Part(78, 105, 8, 4) Middle(2, 0, 4, 2) NoSmooth; + TextureSelectedItemBackground = "Black.png" Part(113, 238, 8, 6) Middle(2, 2) NoSmooth; + DistanceToSide = 5; +} + EditBox { Texture = "Black.png" Part(1, 154, 60, 40) Middle(15, 0) Smooth; TextureHover = "Black.png" Part(63, 196, 60, 40) Middle(15, 0) Smooth; diff --git a/themes/development/Black/Black.txt.in b/themes/development/Black/Black.txt.in index d3d1bb9b1..e80119388 100644 --- a/themes/development/Black/Black.txt.in +++ b/themes/development/Black/Black.txt.in @@ -58,6 +58,12 @@ ComboBox { Padding = (3, 3, 3, 3); } +ContextMenu { + TextureItemBackground = ${MenuBarItem} Middle(2, 0, 4, 2) NoSmooth; + TextureSelectedItemBackground = ${MenuBarItemSelected} Middle(2, 2) NoSmooth; + DistanceToSide = 5; +} + EditBox { Texture = ${EditBoxBackground} Middle(15, 0) Smooth; TextureHover = ${EditBoxBackgroundHover} Middle(15, 0) Smooth; From ef4fe4dd5403314317a72e768ae46b02f8e76e71 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Tue, 7 Jan 2025 19:15:57 +0100 Subject: [PATCH 25/87] Updated copyright to 2025 --- CMakeLists.txt | 2 +- cmake/Dependencies.cmake | 2 +- cmake/Macros.cmake | 2 +- cmake/Modules/FindSDL2.cmake | 2 +- cmake/Modules/Findglfw3.cmake | 2 +- cmake/Modules/Findraylib.cmake | 2 +- cmake/TGUIConfig.cmake.in | 2 +- examples/CMakeLists.txt | 2 +- examples/android/SDL_RENDERER/app/jni/src/example.cpp | 2 +- examples/android/SDL_TTF_GLES2/app/jni/src/example.cpp | 2 +- examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml2.cpp | 2 +- examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml3.cpp | 2 +- examples/iOS/iOS-example-SDL_RENDERER.cpp | 2 +- examples/iOS/iOS-example-SFML_GRAPHICS.cpp | 2 +- examples/main-GLFW_GLES2.cpp | 2 +- examples/main-GLFW_OPENGL3.cpp | 2 +- examples/main-RAYLIB.cpp | 2 +- examples/main-SDL_GLES2.cpp | 2 +- examples/main-SDL_OPENGL3.cpp | 2 +- examples/main-SDL_RENDERER.cpp | 2 +- examples/main-SDL_TTF_GLES2.cpp | 2 +- examples/main-SDL_TTF_OPENGL3.cpp | 2 +- examples/main-SFML_GRAPHICS.cpp | 2 +- examples/main-SFML_OPENGL3.cpp | 2 +- examples/many_different_widgets/ManyDifferentWidgets.cpp | 2 +- examples/scalable_login_screen/ScalableLoginScreen.cpp | 2 +- gui-builder/CMakeLists.txt | 2 +- gui-builder/include/Form.hpp | 2 +- gui-builder/include/GuiBuilder.hpp | 2 +- gui-builder/include/WidgetInfo.hpp | 2 +- gui-builder/include/WidgetProperties/BitmapButtonProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ButtonProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ChatBoxProperties.hpp | 2 +- gui-builder/include/WidgetProperties/CheckBoxProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ChildWindowProperties.hpp | 2 +- .../include/WidgetProperties/ClickableWidgetProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ComboBoxProperties.hpp | 2 +- gui-builder/include/WidgetProperties/EditBoxProperties.hpp | 2 +- .../include/WidgetProperties/EditBoxSliderProperties.hpp | 2 +- gui-builder/include/WidgetProperties/GroupProperties.hpp | 2 +- .../include/WidgetProperties/GrowHorizontalLayoutProperties.hpp | 2 +- .../include/WidgetProperties/GrowVerticalLayoutProperties.hpp | 2 +- .../include/WidgetProperties/HorizontalLayoutProperties.hpp | 2 +- .../include/WidgetProperties/HorizontalWrapProperties.hpp | 2 +- gui-builder/include/WidgetProperties/KnobProperties.hpp | 2 +- gui-builder/include/WidgetProperties/LabelProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ListBoxProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ListViewProperties.hpp | 2 +- gui-builder/include/WidgetProperties/MenuBarProperties.hpp | 2 +- gui-builder/include/WidgetProperties/PanelListBoxProperties.hpp | 2 +- gui-builder/include/WidgetProperties/PanelProperties.hpp | 2 +- gui-builder/include/WidgetProperties/PictureProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ProgressBarProperties.hpp | 2 +- gui-builder/include/WidgetProperties/RadioButtonProperties.hpp | 2 +- gui-builder/include/WidgetProperties/RangeSliderProperties.hpp | 2 +- .../include/WidgetProperties/RichTextLabelProperties.hpp | 2 +- .../include/WidgetProperties/ScrollablePanelProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ScrollbarProperties.hpp | 2 +- .../include/WidgetProperties/SeparatorLineProperties.hpp | 2 +- gui-builder/include/WidgetProperties/SliderProperties.hpp | 2 +- gui-builder/include/WidgetProperties/SpinButtonProperties.hpp | 2 +- gui-builder/include/WidgetProperties/SpinControlProperties.hpp | 2 +- .../include/WidgetProperties/SplitContainerProperties.hpp | 2 +- gui-builder/include/WidgetProperties/TabsProperties.hpp | 2 +- gui-builder/include/WidgetProperties/TextAreaProperties.hpp | 2 +- gui-builder/include/WidgetProperties/ToggleButtonProperties.hpp | 2 +- gui-builder/include/WidgetProperties/TreeViewProperties.hpp | 2 +- .../include/WidgetProperties/VerticalLayoutProperties.hpp | 2 +- gui-builder/include/WidgetProperties/WidgetProperties.hpp | 2 +- gui-builder/src/Form.cpp | 2 +- gui-builder/src/GuiBuilder.cpp | 2 +- gui-builder/src/main.cpp | 2 +- include/TGUI/AbsoluteOrRelativeValue.hpp | 2 +- include/TGUI/AllWidgets.hpp | 2 +- include/TGUI/Animation.hpp | 2 +- include/TGUI/Any.hpp | 2 +- include/TGUI/Backend/Font/BackendFont.hpp | 2 +- include/TGUI/Backend/Font/BackendFontFactory.hpp | 2 +- include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp | 2 +- include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp | 2 +- include/TGUI/Backend/Font/SDL_ttf/BackendFontSDLttf.hpp | 2 +- include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp | 2 +- include/TGUI/Backend/GLFW-GLES2.hpp | 2 +- include/TGUI/Backend/GLFW-OpenGL3.hpp | 2 +- include/TGUI/Backend/Renderer/BackendRenderTarget.hpp | 2 +- include/TGUI/Backend/Renderer/BackendRenderer.hpp | 2 +- include/TGUI/Backend/Renderer/BackendText.hpp | 2 +- include/TGUI/Backend/Renderer/BackendTexture.hpp | 2 +- .../TGUI/Backend/Renderer/GLES2/BackendRenderTargetGLES2.hpp | 2 +- include/TGUI/Backend/Renderer/GLES2/BackendRendererGLES2.hpp | 2 +- include/TGUI/Backend/Renderer/GLES2/BackendTextureGLES2.hpp | 2 +- include/TGUI/Backend/Renderer/GLES2/CanvasGLES2.hpp | 2 +- include/TGUI/Backend/Renderer/OpenGL.hpp | 2 +- .../Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.hpp | 2 +- .../TGUI/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.hpp | 2 +- include/TGUI/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.hpp | 2 +- include/TGUI/Backend/Renderer/OpenGL3/CanvasOpenGL3.hpp | 2 +- .../TGUI/Backend/Renderer/Raylib/BackendRenderTargetRaylib.hpp | 2 +- include/TGUI/Backend/Renderer/Raylib/BackendRendererRaylib.hpp | 2 +- include/TGUI/Backend/Renderer/Raylib/BackendTextureRaylib.hpp | 2 +- include/TGUI/Backend/Renderer/Raylib/CanvasRaylib.hpp | 2 +- .../Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.hpp | 2 +- .../TGUI/Backend/Renderer/SDL_Renderer/BackendRendererSDL.hpp | 2 +- .../TGUI/Backend/Renderer/SDL_Renderer/BackendTextureSDL.hpp | 2 +- include/TGUI/Backend/Renderer/SDL_Renderer/CanvasSDL.hpp | 2 +- .../Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.hpp | 2 +- .../TGUI/Backend/Renderer/SFML-Graphics/BackendRendererSFML.hpp | 2 +- .../TGUI/Backend/Renderer/SFML-Graphics/BackendTextureSFML.hpp | 2 +- include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp | 2 +- include/TGUI/Backend/SDL-GLES2.hpp | 2 +- include/TGUI/Backend/SDL-OpenGL3.hpp | 2 +- include/TGUI/Backend/SDL-Renderer.hpp | 2 +- include/TGUI/Backend/SDL-TTF-GLES2.hpp | 2 +- include/TGUI/Backend/SDL-TTF-OpenGL3.hpp | 2 +- include/TGUI/Backend/SFML-Graphics.hpp | 2 +- include/TGUI/Backend/SFML-OpenGL3.hpp | 2 +- include/TGUI/Backend/Window/Backend.hpp | 2 +- include/TGUI/Backend/Window/BackendGui.hpp | 2 +- include/TGUI/Backend/Window/GLFW/BackendGLFW.hpp | 2 +- include/TGUI/Backend/Window/GLFW/BackendGuiGLFW.hpp | 2 +- include/TGUI/Backend/Window/Raylib/BackendGuiRaylib.hpp | 2 +- include/TGUI/Backend/Window/Raylib/BackendRaylib.hpp | 2 +- include/TGUI/Backend/Window/SDL/BackendGuiSDL.hpp | 2 +- include/TGUI/Backend/Window/SDL/BackendSDL.hpp | 2 +- include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp | 2 +- include/TGUI/Backend/Window/SFML/BackendSFML.hpp | 2 +- include/TGUI/Backend/raylib.hpp | 2 +- include/TGUI/Base64.hpp | 2 +- include/TGUI/Color.hpp | 2 +- include/TGUI/Components.hpp | 2 +- include/TGUI/Config.hpp.in | 2 +- include/TGUI/Container.hpp | 2 +- include/TGUI/CopiedSharedPtr.hpp | 2 +- include/TGUI/Core.hpp | 2 +- include/TGUI/Cursor.hpp | 2 +- include/TGUI/CustomWidgetForBindings.hpp | 2 +- include/TGUI/DefaultBackendWindow.hpp | 2 +- include/TGUI/Duration.hpp | 2 +- include/TGUI/Event.hpp | 2 +- include/TGUI/Exception.hpp | 2 +- include/TGUI/FileDialogIconLoader.hpp | 2 +- include/TGUI/Filesystem.hpp | 2 +- include/TGUI/Font.hpp | 2 +- include/TGUI/Global.hpp | 2 +- include/TGUI/Keyboard.hpp | 2 +- include/TGUI/Layout.hpp | 2 +- include/TGUI/Loading/DataIO.hpp | 2 +- include/TGUI/Loading/Deserializer.hpp | 2 +- include/TGUI/Loading/ImageLoader.hpp | 2 +- include/TGUI/Loading/Serializer.hpp | 2 +- include/TGUI/Loading/Theme.hpp | 2 +- include/TGUI/Loading/ThemeLoader.hpp | 2 +- include/TGUI/Loading/WidgetFactory.hpp | 2 +- include/TGUI/ObjectConverter.hpp | 2 +- include/TGUI/Optional.hpp | 2 +- include/TGUI/Outline.hpp | 2 +- include/TGUI/Rect.hpp | 2 +- include/TGUI/RelFloatRect.hpp | 2 +- include/TGUI/RenderStates.hpp | 2 +- include/TGUI/RendererDefines.hpp | 2 +- include/TGUI/Renderers/BoxLayoutRenderer.hpp | 2 +- include/TGUI/Renderers/ButtonRenderer.hpp | 2 +- include/TGUI/Renderers/ChatBoxRenderer.hpp | 2 +- include/TGUI/Renderers/CheckBoxRenderer.hpp | 2 +- include/TGUI/Renderers/ChildWindowRenderer.hpp | 2 +- include/TGUI/Renderers/ColorPickerRenderer.hpp | 2 +- include/TGUI/Renderers/ComboBoxRenderer.hpp | 2 +- include/TGUI/Renderers/EditBoxRenderer.hpp | 2 +- include/TGUI/Renderers/FileDialogRenderer.hpp | 2 +- include/TGUI/Renderers/GroupRenderer.hpp | 2 +- include/TGUI/Renderers/KnobRenderer.hpp | 2 +- include/TGUI/Renderers/LabelRenderer.hpp | 2 +- include/TGUI/Renderers/ListBoxRenderer.hpp | 2 +- include/TGUI/Renderers/ListViewRenderer.hpp | 2 +- include/TGUI/Renderers/MessageBoxRenderer.hpp | 2 +- include/TGUI/Renderers/PanelListBoxRenderer.hpp | 2 +- include/TGUI/Renderers/PanelRenderer.hpp | 2 +- include/TGUI/Renderers/PictureRenderer.hpp | 2 +- include/TGUI/Renderers/ProgressBarRenderer.hpp | 2 +- include/TGUI/Renderers/RadioButtonRenderer.hpp | 2 +- include/TGUI/Renderers/RangeSliderRenderer.hpp | 2 +- include/TGUI/Renderers/ScrollablePanelRenderer.hpp | 2 +- include/TGUI/Renderers/ScrollbarRenderer.hpp | 2 +- include/TGUI/Renderers/SeparatorLineRenderer.hpp | 2 +- include/TGUI/Renderers/SliderRenderer.hpp | 2 +- include/TGUI/Renderers/SpinButtonRenderer.hpp | 2 +- include/TGUI/Renderers/SplitContainerRenderer.hpp | 2 +- include/TGUI/Renderers/TabsRenderer.hpp | 2 +- include/TGUI/Renderers/TextAreaRenderer.hpp | 2 +- include/TGUI/Renderers/TextBoxRenderer.hpp | 2 +- include/TGUI/Renderers/TreeViewRenderer.hpp | 2 +- include/TGUI/Renderers/WidgetRenderer.hpp | 2 +- include/TGUI/Signal.hpp | 2 +- include/TGUI/SignalManager.hpp | 2 +- include/TGUI/Sprite.hpp | 2 +- include/TGUI/String.hpp | 2 +- include/TGUI/StringView.hpp | 2 +- include/TGUI/SubwidgetContainer.hpp | 2 +- include/TGUI/SvgImage.hpp | 2 +- include/TGUI/TGUI.hpp | 2 +- include/TGUI/Text.hpp | 2 +- include/TGUI/TextStyle.hpp | 2 +- include/TGUI/Texture.hpp | 2 +- include/TGUI/TextureData.hpp | 2 +- include/TGUI/TextureManager.hpp | 2 +- include/TGUI/Timer.hpp | 2 +- include/TGUI/ToolTip.hpp | 2 +- include/TGUI/Transform.hpp | 2 +- include/TGUI/TwoFingerScrollDetect.hpp | 2 +- include/TGUI/Utf.hpp | 2 +- include/TGUI/Variant.hpp | 2 +- include/TGUI/Vector2.hpp | 2 +- include/TGUI/Vertex.hpp | 2 +- include/TGUI/Widget.hpp | 2 +- include/TGUI/Widgets/BitmapButton.hpp | 2 +- include/TGUI/Widgets/BoxLayout.hpp | 2 +- include/TGUI/Widgets/BoxLayoutRatios.hpp | 2 +- include/TGUI/Widgets/Button.hpp | 2 +- include/TGUI/Widgets/ButtonBase.hpp | 2 +- include/TGUI/Widgets/CanvasBase.hpp | 2 +- include/TGUI/Widgets/ChatBox.hpp | 2 +- include/TGUI/Widgets/CheckBox.hpp | 2 +- include/TGUI/Widgets/ChildWindow.hpp | 2 +- include/TGUI/Widgets/ClickableWidget.hpp | 2 +- include/TGUI/Widgets/ColorPicker.hpp | 2 +- include/TGUI/Widgets/ComboBox.hpp | 2 +- include/TGUI/Widgets/EditBox.hpp | 2 +- include/TGUI/Widgets/FileDialog.hpp | 2 +- include/TGUI/Widgets/Grid.hpp | 2 +- include/TGUI/Widgets/Group.hpp | 2 +- include/TGUI/Widgets/GrowHorizontalLayout.hpp | 2 +- include/TGUI/Widgets/GrowVerticalLayout.hpp | 2 +- include/TGUI/Widgets/HorizontalLayout.hpp | 2 +- include/TGUI/Widgets/HorizontalWrap.hpp | 2 +- include/TGUI/Widgets/Knob.hpp | 2 +- include/TGUI/Widgets/Label.hpp | 2 +- include/TGUI/Widgets/ListBox.hpp | 2 +- include/TGUI/Widgets/ListView.hpp | 2 +- include/TGUI/Widgets/MessageBox.hpp | 2 +- include/TGUI/Widgets/Panel.hpp | 2 +- include/TGUI/Widgets/PanelListBox.hpp | 2 +- include/TGUI/Widgets/Picture.hpp | 2 +- include/TGUI/Widgets/ProgressBar.hpp | 2 +- include/TGUI/Widgets/RadioButton.hpp | 2 +- include/TGUI/Widgets/RadioButtonGroup.hpp | 2 +- include/TGUI/Widgets/RangeSlider.hpp | 2 +- include/TGUI/Widgets/RichTextLabel.hpp | 2 +- include/TGUI/Widgets/ScrollablePanel.hpp | 2 +- include/TGUI/Widgets/Scrollbar.hpp | 2 +- include/TGUI/Widgets/SeparatorLine.hpp | 2 +- include/TGUI/Widgets/Slider.hpp | 2 +- include/TGUI/Widgets/SpinButton.hpp | 2 +- include/TGUI/Widgets/SpinControl.hpp | 2 +- include/TGUI/Widgets/SplitContainer.hpp | 2 +- include/TGUI/Widgets/TabContainer.hpp | 2 +- include/TGUI/Widgets/Tabs.hpp | 2 +- include/TGUI/Widgets/TextArea.hpp | 2 +- include/TGUI/Widgets/ToggleButton.hpp | 2 +- include/TGUI/Widgets/TreeView.hpp | 2 +- include/TGUI/Widgets/VerticalLayout.hpp | 2 +- include/TGUI/WindowsIMM.hpp | 2 +- include/TGUI/extlibs/IncludeNanoSVG.hpp | 2 +- include/TGUI/extlibs/IncludeSDL.hpp | 2 +- include/TGUI/extlibs/IncludeStbImage.hpp | 2 +- include/TGUI/extlibs/IncludeStbImageWrite.hpp | 2 +- include/TGUI/extlibs/IncludeWindows.hpp | 2 +- license.txt | 2 +- src/Animation.cpp | 2 +- src/Backend/CMakeLists.txt | 2 +- src/Backend/Font/BackendFont.cpp | 2 +- src/Backend/Font/FreeType/BackendFontFreeType.cpp | 2 +- src/Backend/Font/Raylib/BackendFontRaylib.cpp | 2 +- src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp | 2 +- src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp | 2 +- src/Backend/GLFW-GLES2.cpp | 2 +- src/Backend/GLFW-OpenGL3.cpp | 2 +- src/Backend/Renderer/BackendRenderTarget.cpp | 2 +- src/Backend/Renderer/BackendText.cpp | 2 +- src/Backend/Renderer/BackendTexture.cpp | 2 +- src/Backend/Renderer/GLES2/BackendRenderTargetGLES2.cpp | 2 +- src/Backend/Renderer/GLES2/BackendRendererGLES2.cpp | 2 +- src/Backend/Renderer/GLES2/BackendTextureGLES2.cpp | 2 +- src/Backend/Renderer/GLES2/CanvasGLES2.cpp | 2 +- src/Backend/Renderer/OpenGL.cpp | 2 +- src/Backend/Renderer/OpenGL.cppm | 2 +- src/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.cpp | 2 +- src/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.cpp | 2 +- src/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.cpp | 2 +- src/Backend/Renderer/OpenGL3/CanvasOpenGL3.cpp | 2 +- src/Backend/Renderer/Raylib/BackendRenderTargetRaylib.cpp | 2 +- src/Backend/Renderer/Raylib/BackendRendererRaylib.cpp | 2 +- src/Backend/Renderer/Raylib/BackendTextureRaylib.cpp | 2 +- src/Backend/Renderer/Raylib/CanvasRaylib.cpp | 2 +- src/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.cpp | 2 +- src/Backend/Renderer/SDL_Renderer/BackendRendererSDL.cpp | 2 +- src/Backend/Renderer/SDL_Renderer/BackendTextureSDL.cpp | 2 +- src/Backend/Renderer/SDL_Renderer/CanvasSDL.cpp | 2 +- src/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.cpp | 2 +- src/Backend/Renderer/SFML-Graphics/BackendRendererSFML.cpp | 2 +- src/Backend/Renderer/SFML-Graphics/BackendTextureSFML.cpp | 2 +- src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp | 2 +- src/Backend/SDL-GLES2.cpp | 2 +- src/Backend/SDL-OpenGL3.cpp | 2 +- src/Backend/SDL-Renderer.cpp | 2 +- src/Backend/SDL-TTF-GLES2.cpp | 2 +- src/Backend/SDL-TTF-OpenGL3.cpp | 2 +- src/Backend/SFML-Graphics.cpp | 2 +- src/Backend/SFML-OpenGL3.cpp | 2 +- src/Backend/Window/Backend.cpp | 2 +- src/Backend/Window/BackendGui.cpp | 2 +- src/Backend/Window/GLFW/BackendGLFW.cpp | 2 +- src/Backend/Window/GLFW/BackendGuiGLFW.cpp | 2 +- src/Backend/Window/Raylib/BackendGuiRaylib.cpp | 2 +- src/Backend/Window/Raylib/BackendRaylib.cpp | 2 +- src/Backend/Window/SDL/BackendGuiSDL.cpp | 2 +- src/Backend/Window/SDL/BackendSDL.cpp | 2 +- src/Backend/Window/SFML/BackendGuiSFML.cpp | 2 +- src/Backend/Window/SFML/BackendSFML.cpp | 2 +- src/Backend/raylib.cpp | 2 +- src/Base64.cpp | 2 +- src/CMakeLists.txt | 2 +- src/Color.cpp | 2 +- src/Components.cpp | 2 +- src/Container.cpp | 2 +- src/Cursor.cpp | 2 +- src/CustomWidgetForBindings.cpp | 2 +- src/DefaultBackendWindow.cpp | 2 +- src/FileDialogIconLoader.cpp | 2 +- src/FileDialogIconLoaderLinux.cpp | 2 +- src/FileDialogIconLoaderWindows.cpp | 2 +- src/Filesystem.cpp | 2 +- src/Font.cpp | 2 +- src/Global.cpp | 2 +- src/Layout.cpp | 2 +- src/Loading/DataIO.cpp | 2 +- src/Loading/Deserializer.cpp | 2 +- src/Loading/ImageLoader.cpp | 2 +- src/Loading/Serializer.cpp | 2 +- src/Loading/Theme.cpp | 2 +- src/Loading/ThemeLoader.cpp | 2 +- src/Loading/WidgetFactory.cpp | 2 +- src/ObjectConverter.cpp | 2 +- src/Renderers/BoxLayoutRenderer.cpp | 2 +- src/Renderers/ButtonRenderer.cpp | 2 +- src/Renderers/ChatBoxRenderer.cpp | 2 +- src/Renderers/ChildWindowRenderer.cpp | 2 +- src/Renderers/ColorPickerRenderer.cpp | 2 +- src/Renderers/ComboBoxRenderer.cpp | 2 +- src/Renderers/EditBoxRenderer.cpp | 2 +- src/Renderers/FileDialogRenderer.cpp | 2 +- src/Renderers/GroupRenderer.cpp | 2 +- src/Renderers/KnobRenderer.cpp | 2 +- src/Renderers/LabelRenderer.cpp | 2 +- src/Renderers/ListBoxRenderer.cpp | 2 +- src/Renderers/ListViewRenderer.cpp | 2 +- src/Renderers/MessageBoxRenderer.cpp | 2 +- src/Renderers/PanelListBoxRenderer.cpp | 2 +- src/Renderers/PanelRenderer.cpp | 2 +- src/Renderers/PictureRenderer.cpp | 2 +- src/Renderers/ProgressBarRenderer.cpp | 2 +- src/Renderers/RadioButtonRenderer.cpp | 2 +- src/Renderers/RangeSliderRenderer.cpp | 2 +- src/Renderers/ScrollablePanelRenderer.cpp | 2 +- src/Renderers/ScrollbarRenderer.cpp | 2 +- src/Renderers/SeparatorLineRenderer.cpp | 2 +- src/Renderers/SliderRenderer.cpp | 2 +- src/Renderers/SpinButtonRenderer.cpp | 2 +- src/Renderers/SplitContainerRenderer.cpp | 2 +- src/Renderers/TabsRenderer.cpp | 2 +- src/Renderers/TextAreaRenderer.cpp | 2 +- src/Renderers/TreeViewRenderer.cpp | 2 +- src/Renderers/WidgetRenderer.cpp | 2 +- src/Signal.cpp | 2 +- src/SignalManager.cpp | 2 +- src/Sprite.cpp | 2 +- src/String.cpp | 2 +- src/SubwidgetContainer.cpp | 2 +- src/SvgImage.cpp | 2 +- src/TGUI-Main-Module.cppm.in | 2 +- src/TGUI-Module.cppm.in | 2 +- src/Text.cpp | 2 +- src/TextStyle.cpp | 2 +- src/Texture.cpp | 2 +- src/TextureManager.cpp | 2 +- src/Timer.cpp | 2 +- src/ToolTip.cpp | 2 +- src/Transform.cpp | 2 +- src/TwoFingerScrollDetect.cpp | 2 +- src/Widget.cpp | 2 +- src/Widgets/BitmapButton.cpp | 2 +- src/Widgets/BoxLayout.cpp | 2 +- src/Widgets/BoxLayoutRatios.cpp | 2 +- src/Widgets/Button.cpp | 2 +- src/Widgets/ButtonBase.cpp | 2 +- src/Widgets/CanvasBase.cpp | 2 +- src/Widgets/ChatBox.cpp | 2 +- src/Widgets/CheckBox.cpp | 2 +- src/Widgets/ChildWindow.cpp | 2 +- src/Widgets/ClickableWidget.cpp | 2 +- src/Widgets/ColorPicker.cpp | 2 +- src/Widgets/ComboBox.cpp | 2 +- src/Widgets/EditBox.cpp | 2 +- src/Widgets/FileDialog.cpp | 2 +- src/Widgets/Grid.cpp | 2 +- src/Widgets/Group.cpp | 2 +- src/Widgets/GrowHorizontalLayout.cpp | 2 +- src/Widgets/GrowVerticalLayout.cpp | 2 +- src/Widgets/HorizontalLayout.cpp | 2 +- src/Widgets/HorizontalWrap.cpp | 2 +- src/Widgets/Knob.cpp | 2 +- src/Widgets/Label.cpp | 2 +- src/Widgets/ListBox.cpp | 2 +- src/Widgets/ListView.cpp | 2 +- src/Widgets/MessageBox.cpp | 2 +- src/Widgets/Panel.cpp | 2 +- src/Widgets/PanelListBox.cpp | 2 +- src/Widgets/Picture.cpp | 2 +- src/Widgets/ProgressBar.cpp | 2 +- src/Widgets/RadioButton.cpp | 2 +- src/Widgets/RadioButtonGroup.cpp | 2 +- src/Widgets/RangeSlider.cpp | 2 +- src/Widgets/RichTextLabel.cpp | 2 +- src/Widgets/ScrollablePanel.cpp | 2 +- src/Widgets/Scrollbar.cpp | 2 +- src/Widgets/SeparatorLine.cpp | 2 +- src/Widgets/Slider.cpp | 2 +- src/Widgets/SpinButton.cpp | 2 +- src/Widgets/SpinControl.cpp | 2 +- src/Widgets/SplitContainer.cpp | 2 +- src/Widgets/TabContainer.cpp | 2 +- src/Widgets/Tabs.cpp | 2 +- src/Widgets/TextArea.cpp | 2 +- src/Widgets/ToggleButton.cpp | 2 +- src/Widgets/TreeView.cpp | 2 +- src/Widgets/VerticalLayout.cpp | 2 +- src/WindowsIMM.cpp | 2 +- tests/AbsoluteOrRelativeValue.cpp | 2 +- tests/Animation.cpp | 2 +- tests/BackendEvents.cpp | 2 +- tests/CMakeLists.txt | 2 +- tests/Clipboard.cpp | 2 +- tests/Clipping.cpp | 2 +- tests/Color.cpp | 2 +- tests/CompareFiles.cpp | 2 +- tests/Container.cpp | 2 +- tests/Duration.cpp | 2 +- tests/Filesystem.cpp | 2 +- tests/Focus.cpp | 2 +- tests/Font.cpp | 2 +- tests/Layouts.cpp | 2 +- tests/Loading/DataIO.cpp | 2 +- tests/Loading/Deserializer.cpp | 2 +- tests/Loading/Serializer.cpp | 2 +- tests/Loading/Theme.cpp | 2 +- tests/Loading/ThemeLoader.cpp | 2 +- tests/MouseCursors.cpp | 2 +- tests/Outline.cpp | 2 +- tests/Signal.cpp | 2 +- tests/SignalManager.cpp | 2 +- tests/Sprite.cpp | 2 +- tests/String.cpp | 2 +- tests/SvgImage.cpp | 2 +- tests/Tests.cpp | 2 +- tests/Tests.hpp | 2 +- tests/Text.cpp | 2 +- tests/Texture.cpp | 2 +- tests/TextureManager.cpp | 2 +- tests/Timer.cpp | 2 +- tests/ToolTip.cpp | 2 +- tests/Vector2.cpp | 2 +- tests/Widget.cpp | 2 +- tests/Widgets/BitmapButton.cpp | 2 +- tests/Widgets/Button.cpp | 2 +- tests/Widgets/Canvas.cpp | 2 +- tests/Widgets/ChatBox.cpp | 2 +- tests/Widgets/CheckBox.cpp | 2 +- tests/Widgets/ChildWindow.cpp | 2 +- tests/Widgets/ClickableWidget.cpp | 2 +- tests/Widgets/ColorPicker.cpp | 2 +- tests/Widgets/ComboBox.cpp | 2 +- tests/Widgets/EditBox.cpp | 2 +- tests/Widgets/EditBoxSlider.cpp | 2 +- tests/Widgets/FileDialog.cpp | 2 +- tests/Widgets/Grid.cpp | 2 +- tests/Widgets/Group.cpp | 2 +- tests/Widgets/GrowHorizontalLayout.cpp | 2 +- tests/Widgets/GrowVerticalLayout.cpp | 2 +- tests/Widgets/HorizontalLayout.cpp | 2 +- tests/Widgets/HorizontalWrap.cpp | 2 +- tests/Widgets/Knob.cpp | 2 +- tests/Widgets/Label.cpp | 2 +- tests/Widgets/ListBox.cpp | 2 +- tests/Widgets/ListView.cpp | 2 +- tests/Widgets/MenuBar.cpp | 2 +- tests/Widgets/MessageBox.cpp | 2 +- tests/Widgets/Panel.cpp | 2 +- tests/Widgets/PanelListBox.cpp | 2 +- tests/Widgets/Picture.cpp | 2 +- tests/Widgets/ProgressBar.cpp | 2 +- tests/Widgets/RadioButton.cpp | 2 +- tests/Widgets/RadioButtonGroup.cpp | 2 +- tests/Widgets/RangeSlider.cpp | 2 +- tests/Widgets/RichTextLabel.cpp | 2 +- tests/Widgets/ScrollablePanel.cpp | 2 +- tests/Widgets/Scrollbar.cpp | 2 +- tests/Widgets/SeparatorLine.cpp | 2 +- tests/Widgets/Slider.cpp | 2 +- tests/Widgets/SpinButton.cpp | 2 +- tests/Widgets/SpinControl.cpp | 2 +- tests/Widgets/SplitContainer.cpp | 2 +- tests/Widgets/TabContainer.cpp | 2 +- tests/Widgets/Tabs.cpp | 2 +- tests/Widgets/TextArea.cpp | 2 +- tests/Widgets/ToggleButton.cpp | 2 +- tests/Widgets/TreeView.cpp | 2 +- tests/Widgets/VerticalLayout.cpp | 2 +- 516 files changed, 516 insertions(+), 516 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index effb1beeb..6f3cc9aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 72aa1e814..67e1f524e 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index 0cefd5005..48018b83e 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake index 9ab7a7016..6ebbbb7e3 100644 --- a/cmake/Modules/FindSDL2.cmake +++ b/cmake/Modules/FindSDL2.cmake @@ -1,7 +1,7 @@ # Distributed under the OSI-approved BSD 3-Clause License. # See https://cmake.org/licensing for details. -# Copyright 2021-2024 Bruno Van de Velde +# Copyright 2021-2025 Bruno Van de Velde # Copyright 2019 Amine Ben Hassouna # Copyright 2000-2019 Kitware, Inc. and Contributors # All rights reserved. diff --git a/cmake/Modules/Findglfw3.cmake b/cmake/Modules/Findglfw3.cmake index 2bcf545bf..2b61235cd 100644 --- a/cmake/Modules/Findglfw3.cmake +++ b/cmake/Modules/Findglfw3.cmake @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/cmake/Modules/Findraylib.cmake b/cmake/Modules/Findraylib.cmake index 4ebe23ecd..4f55b91e5 100644 --- a/cmake/Modules/Findraylib.cmake +++ b/cmake/Modules/Findraylib.cmake @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/cmake/TGUIConfig.cmake.in b/cmake/TGUIConfig.cmake.in index 279fe3cc4..173d61aa4 100644 --- a/cmake/TGUIConfig.cmake.in +++ b/cmake/TGUIConfig.cmake.in @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cf2e3b294..59ace0836 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/android/SDL_RENDERER/app/jni/src/example.cpp b/examples/android/SDL_RENDERER/app/jni/src/example.cpp index 68470d1f2..8f20393f6 100644 --- a/examples/android/SDL_RENDERER/app/jni/src/example.cpp +++ b/examples/android/SDL_RENDERER/app/jni/src/example.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/android/SDL_TTF_GLES2/app/jni/src/example.cpp b/examples/android/SDL_TTF_GLES2/app/jni/src/example.cpp index 0e46545d2..cffa769ce 100644 --- a/examples/android/SDL_TTF_GLES2/app/jni/src/example.cpp +++ b/examples/android/SDL_TTF_GLES2/app/jni/src/example.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml2.cpp b/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml2.cpp index 30a9332a1..35e1494de 100644 --- a/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml2.cpp +++ b/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml3.cpp b/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml3.cpp index 344ad4330..86e59966d 100644 --- a/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml3.cpp +++ b/examples/android/SFML_GRAPHICS/app/src/main/jni/main-sfml3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/iOS/iOS-example-SDL_RENDERER.cpp b/examples/iOS/iOS-example-SDL_RENDERER.cpp index a3c67667b..837000ece 100644 --- a/examples/iOS/iOS-example-SDL_RENDERER.cpp +++ b/examples/iOS/iOS-example-SDL_RENDERER.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/iOS/iOS-example-SFML_GRAPHICS.cpp b/examples/iOS/iOS-example-SFML_GRAPHICS.cpp index ff23a18bb..de4e45e6b 100644 --- a/examples/iOS/iOS-example-SFML_GRAPHICS.cpp +++ b/examples/iOS/iOS-example-SFML_GRAPHICS.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-GLFW_GLES2.cpp b/examples/main-GLFW_GLES2.cpp index 642f90f7e..e2600426d 100644 --- a/examples/main-GLFW_GLES2.cpp +++ b/examples/main-GLFW_GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-GLFW_OPENGL3.cpp b/examples/main-GLFW_OPENGL3.cpp index 218987aca..cc910c37f 100644 --- a/examples/main-GLFW_OPENGL3.cpp +++ b/examples/main-GLFW_OPENGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-RAYLIB.cpp b/examples/main-RAYLIB.cpp index 38293f50a..002e8f1d1 100644 --- a/examples/main-RAYLIB.cpp +++ b/examples/main-RAYLIB.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SDL_GLES2.cpp b/examples/main-SDL_GLES2.cpp index 505394585..0a8c620dc 100644 --- a/examples/main-SDL_GLES2.cpp +++ b/examples/main-SDL_GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SDL_OPENGL3.cpp b/examples/main-SDL_OPENGL3.cpp index e8a1ebbc2..fd749ec42 100644 --- a/examples/main-SDL_OPENGL3.cpp +++ b/examples/main-SDL_OPENGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SDL_RENDERER.cpp b/examples/main-SDL_RENDERER.cpp index 5b3761252..a211a534f 100644 --- a/examples/main-SDL_RENDERER.cpp +++ b/examples/main-SDL_RENDERER.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SDL_TTF_GLES2.cpp b/examples/main-SDL_TTF_GLES2.cpp index dcefe09e2..80560ac26 100644 --- a/examples/main-SDL_TTF_GLES2.cpp +++ b/examples/main-SDL_TTF_GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SDL_TTF_OPENGL3.cpp b/examples/main-SDL_TTF_OPENGL3.cpp index dab9a44b4..d29c9e29f 100644 --- a/examples/main-SDL_TTF_OPENGL3.cpp +++ b/examples/main-SDL_TTF_OPENGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SFML_GRAPHICS.cpp b/examples/main-SFML_GRAPHICS.cpp index f55e1fc44..2305e8bbc 100644 --- a/examples/main-SFML_GRAPHICS.cpp +++ b/examples/main-SFML_GRAPHICS.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/main-SFML_OPENGL3.cpp b/examples/main-SFML_OPENGL3.cpp index 098044972..a2c88d6b7 100644 --- a/examples/main-SFML_OPENGL3.cpp +++ b/examples/main-SFML_OPENGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/many_different_widgets/ManyDifferentWidgets.cpp b/examples/many_different_widgets/ManyDifferentWidgets.cpp index 068a53e88..bf8076c53 100644 --- a/examples/many_different_widgets/ManyDifferentWidgets.cpp +++ b/examples/many_different_widgets/ManyDifferentWidgets.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/scalable_login_screen/ScalableLoginScreen.cpp b/examples/scalable_login_screen/ScalableLoginScreen.cpp index 9970d5ef1..58794d44b 100644 --- a/examples/scalable_login_screen/ScalableLoginScreen.cpp +++ b/examples/scalable_login_screen/ScalableLoginScreen.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/CMakeLists.txt b/gui-builder/CMakeLists.txt index aacea6b35..7d809029c 100644 --- a/gui-builder/CMakeLists.txt +++ b/gui-builder/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/Form.hpp b/gui-builder/include/Form.hpp index 3d4eaabd1..47a20997b 100644 --- a/gui-builder/include/Form.hpp +++ b/gui-builder/include/Form.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/GuiBuilder.hpp b/gui-builder/include/GuiBuilder.hpp index beddda3aa..efe9e05a2 100644 --- a/gui-builder/include/GuiBuilder.hpp +++ b/gui-builder/include/GuiBuilder.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetInfo.hpp b/gui-builder/include/WidgetInfo.hpp index 533b09f8c..904fd20f9 100644 --- a/gui-builder/include/WidgetInfo.hpp +++ b/gui-builder/include/WidgetInfo.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/BitmapButtonProperties.hpp b/gui-builder/include/WidgetProperties/BitmapButtonProperties.hpp index 88ad5c494..8855962b3 100644 --- a/gui-builder/include/WidgetProperties/BitmapButtonProperties.hpp +++ b/gui-builder/include/WidgetProperties/BitmapButtonProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ButtonProperties.hpp b/gui-builder/include/WidgetProperties/ButtonProperties.hpp index 55fbbd899..65dc72b77 100644 --- a/gui-builder/include/WidgetProperties/ButtonProperties.hpp +++ b/gui-builder/include/WidgetProperties/ButtonProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ChatBoxProperties.hpp b/gui-builder/include/WidgetProperties/ChatBoxProperties.hpp index 3d57fc2c6..939c1d511 100644 --- a/gui-builder/include/WidgetProperties/ChatBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/ChatBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/CheckBoxProperties.hpp b/gui-builder/include/WidgetProperties/CheckBoxProperties.hpp index 08ca5693a..2d5284262 100644 --- a/gui-builder/include/WidgetProperties/CheckBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/CheckBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ChildWindowProperties.hpp b/gui-builder/include/WidgetProperties/ChildWindowProperties.hpp index f629b2cd2..ef671972e 100644 --- a/gui-builder/include/WidgetProperties/ChildWindowProperties.hpp +++ b/gui-builder/include/WidgetProperties/ChildWindowProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ClickableWidgetProperties.hpp b/gui-builder/include/WidgetProperties/ClickableWidgetProperties.hpp index ca2e9b78b..53d9fba3c 100644 --- a/gui-builder/include/WidgetProperties/ClickableWidgetProperties.hpp +++ b/gui-builder/include/WidgetProperties/ClickableWidgetProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ComboBoxProperties.hpp b/gui-builder/include/WidgetProperties/ComboBoxProperties.hpp index d3f4c94f6..52844dcd5 100644 --- a/gui-builder/include/WidgetProperties/ComboBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/ComboBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/EditBoxProperties.hpp b/gui-builder/include/WidgetProperties/EditBoxProperties.hpp index f9b373c53..949413ebd 100644 --- a/gui-builder/include/WidgetProperties/EditBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/EditBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/EditBoxSliderProperties.hpp b/gui-builder/include/WidgetProperties/EditBoxSliderProperties.hpp index 01e15dcd3..b8cbac750 100644 --- a/gui-builder/include/WidgetProperties/EditBoxSliderProperties.hpp +++ b/gui-builder/include/WidgetProperties/EditBoxSliderProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/GroupProperties.hpp b/gui-builder/include/WidgetProperties/GroupProperties.hpp index 1583e674e..39409b00d 100644 --- a/gui-builder/include/WidgetProperties/GroupProperties.hpp +++ b/gui-builder/include/WidgetProperties/GroupProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp index 133f971d3..bf2d7ca92 100644 --- a/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp +++ b/gui-builder/include/WidgetProperties/GrowHorizontalLayoutProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp index a700edcdc..f69e7ad17 100644 --- a/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp +++ b/gui-builder/include/WidgetProperties/GrowVerticalLayoutProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/HorizontalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/HorizontalLayoutProperties.hpp index c0bc9e747..38961bb02 100644 --- a/gui-builder/include/WidgetProperties/HorizontalLayoutProperties.hpp +++ b/gui-builder/include/WidgetProperties/HorizontalLayoutProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/HorizontalWrapProperties.hpp b/gui-builder/include/WidgetProperties/HorizontalWrapProperties.hpp index eb722a0d4..4e35850e0 100644 --- a/gui-builder/include/WidgetProperties/HorizontalWrapProperties.hpp +++ b/gui-builder/include/WidgetProperties/HorizontalWrapProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/KnobProperties.hpp b/gui-builder/include/WidgetProperties/KnobProperties.hpp index 1d54d1975..ca0ee3d8e 100644 --- a/gui-builder/include/WidgetProperties/KnobProperties.hpp +++ b/gui-builder/include/WidgetProperties/KnobProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/LabelProperties.hpp b/gui-builder/include/WidgetProperties/LabelProperties.hpp index 8ffb3ab28..da20a524b 100644 --- a/gui-builder/include/WidgetProperties/LabelProperties.hpp +++ b/gui-builder/include/WidgetProperties/LabelProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ListBoxProperties.hpp b/gui-builder/include/WidgetProperties/ListBoxProperties.hpp index e52aa7f69..76055fa87 100644 --- a/gui-builder/include/WidgetProperties/ListBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/ListBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ListViewProperties.hpp b/gui-builder/include/WidgetProperties/ListViewProperties.hpp index 1b0eba2f0..35857bb23 100644 --- a/gui-builder/include/WidgetProperties/ListViewProperties.hpp +++ b/gui-builder/include/WidgetProperties/ListViewProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/MenuBarProperties.hpp b/gui-builder/include/WidgetProperties/MenuBarProperties.hpp index fe27a4473..e4126bd56 100644 --- a/gui-builder/include/WidgetProperties/MenuBarProperties.hpp +++ b/gui-builder/include/WidgetProperties/MenuBarProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/PanelListBoxProperties.hpp b/gui-builder/include/WidgetProperties/PanelListBoxProperties.hpp index 3be9d1f5f..09296feca 100644 --- a/gui-builder/include/WidgetProperties/PanelListBoxProperties.hpp +++ b/gui-builder/include/WidgetProperties/PanelListBoxProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/PanelProperties.hpp b/gui-builder/include/WidgetProperties/PanelProperties.hpp index aa6ca5c64..1e3e89147 100644 --- a/gui-builder/include/WidgetProperties/PanelProperties.hpp +++ b/gui-builder/include/WidgetProperties/PanelProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/PictureProperties.hpp b/gui-builder/include/WidgetProperties/PictureProperties.hpp index 0070a02aa..a5db88db0 100644 --- a/gui-builder/include/WidgetProperties/PictureProperties.hpp +++ b/gui-builder/include/WidgetProperties/PictureProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ProgressBarProperties.hpp b/gui-builder/include/WidgetProperties/ProgressBarProperties.hpp index fc7cabfed..92d596613 100644 --- a/gui-builder/include/WidgetProperties/ProgressBarProperties.hpp +++ b/gui-builder/include/WidgetProperties/ProgressBarProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/RadioButtonProperties.hpp b/gui-builder/include/WidgetProperties/RadioButtonProperties.hpp index 5fe323412..f987fa61d 100644 --- a/gui-builder/include/WidgetProperties/RadioButtonProperties.hpp +++ b/gui-builder/include/WidgetProperties/RadioButtonProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/RangeSliderProperties.hpp b/gui-builder/include/WidgetProperties/RangeSliderProperties.hpp index 09495f334..2746ef4c2 100644 --- a/gui-builder/include/WidgetProperties/RangeSliderProperties.hpp +++ b/gui-builder/include/WidgetProperties/RangeSliderProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/RichTextLabelProperties.hpp b/gui-builder/include/WidgetProperties/RichTextLabelProperties.hpp index 86909ca96..6151963ff 100644 --- a/gui-builder/include/WidgetProperties/RichTextLabelProperties.hpp +++ b/gui-builder/include/WidgetProperties/RichTextLabelProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ScrollablePanelProperties.hpp b/gui-builder/include/WidgetProperties/ScrollablePanelProperties.hpp index f5083fc86..84e38eb1c 100644 --- a/gui-builder/include/WidgetProperties/ScrollablePanelProperties.hpp +++ b/gui-builder/include/WidgetProperties/ScrollablePanelProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ScrollbarProperties.hpp b/gui-builder/include/WidgetProperties/ScrollbarProperties.hpp index 16c790e94..63772ffef 100644 --- a/gui-builder/include/WidgetProperties/ScrollbarProperties.hpp +++ b/gui-builder/include/WidgetProperties/ScrollbarProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/SeparatorLineProperties.hpp b/gui-builder/include/WidgetProperties/SeparatorLineProperties.hpp index 94e3be394..426642f10 100644 --- a/gui-builder/include/WidgetProperties/SeparatorLineProperties.hpp +++ b/gui-builder/include/WidgetProperties/SeparatorLineProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/SliderProperties.hpp b/gui-builder/include/WidgetProperties/SliderProperties.hpp index d0f1c457d..4c4bb0102 100644 --- a/gui-builder/include/WidgetProperties/SliderProperties.hpp +++ b/gui-builder/include/WidgetProperties/SliderProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/SpinButtonProperties.hpp b/gui-builder/include/WidgetProperties/SpinButtonProperties.hpp index 921ba029e..76d14aebe 100644 --- a/gui-builder/include/WidgetProperties/SpinButtonProperties.hpp +++ b/gui-builder/include/WidgetProperties/SpinButtonProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/SpinControlProperties.hpp b/gui-builder/include/WidgetProperties/SpinControlProperties.hpp index 3dce47be8..c069d1baa 100644 --- a/gui-builder/include/WidgetProperties/SpinControlProperties.hpp +++ b/gui-builder/include/WidgetProperties/SpinControlProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/SplitContainerProperties.hpp b/gui-builder/include/WidgetProperties/SplitContainerProperties.hpp index 8c3ba17d7..61e31b805 100644 --- a/gui-builder/include/WidgetProperties/SplitContainerProperties.hpp +++ b/gui-builder/include/WidgetProperties/SplitContainerProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/TabsProperties.hpp b/gui-builder/include/WidgetProperties/TabsProperties.hpp index b50388d95..7ce8b084e 100644 --- a/gui-builder/include/WidgetProperties/TabsProperties.hpp +++ b/gui-builder/include/WidgetProperties/TabsProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/TextAreaProperties.hpp b/gui-builder/include/WidgetProperties/TextAreaProperties.hpp index 1466f3c38..0eaf02e43 100644 --- a/gui-builder/include/WidgetProperties/TextAreaProperties.hpp +++ b/gui-builder/include/WidgetProperties/TextAreaProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/ToggleButtonProperties.hpp b/gui-builder/include/WidgetProperties/ToggleButtonProperties.hpp index 76428db09..fb1a56fe9 100644 --- a/gui-builder/include/WidgetProperties/ToggleButtonProperties.hpp +++ b/gui-builder/include/WidgetProperties/ToggleButtonProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/TreeViewProperties.hpp b/gui-builder/include/WidgetProperties/TreeViewProperties.hpp index 47fb378f6..43297c1c1 100644 --- a/gui-builder/include/WidgetProperties/TreeViewProperties.hpp +++ b/gui-builder/include/WidgetProperties/TreeViewProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/VerticalLayoutProperties.hpp b/gui-builder/include/WidgetProperties/VerticalLayoutProperties.hpp index ec19b6e50..8e5930277 100644 --- a/gui-builder/include/WidgetProperties/VerticalLayoutProperties.hpp +++ b/gui-builder/include/WidgetProperties/VerticalLayoutProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/include/WidgetProperties/WidgetProperties.hpp b/gui-builder/include/WidgetProperties/WidgetProperties.hpp index 5dfab106a..b19ecc5fe 100644 --- a/gui-builder/include/WidgetProperties/WidgetProperties.hpp +++ b/gui-builder/include/WidgetProperties/WidgetProperties.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/src/Form.cpp b/gui-builder/src/Form.cpp index 35bd5a1ea..ddcafb7ac 100644 --- a/gui-builder/src/Form.cpp +++ b/gui-builder/src/Form.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/src/GuiBuilder.cpp b/gui-builder/src/GuiBuilder.cpp index ef59d8c8b..e00cb3f38 100644 --- a/gui-builder/src/GuiBuilder.cpp +++ b/gui-builder/src/GuiBuilder.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/gui-builder/src/main.cpp b/gui-builder/src/main.cpp index d3fe6c352..afb58f82d 100644 --- a/gui-builder/src/main.cpp +++ b/gui-builder/src/main.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/AbsoluteOrRelativeValue.hpp b/include/TGUI/AbsoluteOrRelativeValue.hpp index 6a7ca147d..f70d3db4f 100644 --- a/include/TGUI/AbsoluteOrRelativeValue.hpp +++ b/include/TGUI/AbsoluteOrRelativeValue.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/AllWidgets.hpp b/include/TGUI/AllWidgets.hpp index 518755abc..aa8d26c74 100644 --- a/include/TGUI/AllWidgets.hpp +++ b/include/TGUI/AllWidgets.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Animation.hpp b/include/TGUI/Animation.hpp index f4b8c7ad3..38da279cf 100644 --- a/include/TGUI/Animation.hpp +++ b/include/TGUI/Animation.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Any.hpp b/include/TGUI/Any.hpp index 79613d7ff..3f29c94c2 100644 --- a/include/TGUI/Any.hpp +++ b/include/TGUI/Any.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/BackendFont.hpp b/include/TGUI/Backend/Font/BackendFont.hpp index a6cdd8f15..53e7adfc9 100644 --- a/include/TGUI/Backend/Font/BackendFont.hpp +++ b/include/TGUI/Backend/Font/BackendFont.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/BackendFontFactory.hpp b/include/TGUI/Backend/Font/BackendFontFactory.hpp index be0c5672c..ae3870d2b 100644 --- a/include/TGUI/Backend/Font/BackendFontFactory.hpp +++ b/include/TGUI/Backend/Font/BackendFontFactory.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp b/include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp index db688fc30..1853f98cb 100644 --- a/include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp +++ b/include/TGUI/Backend/Font/FreeType/BackendFontFreeType.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp b/include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp index 6f294c469..c8b121c96 100644 --- a/include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp +++ b/include/TGUI/Backend/Font/Raylib/BackendFontRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/SDL_ttf/BackendFontSDLttf.hpp b/include/TGUI/Backend/Font/SDL_ttf/BackendFontSDLttf.hpp index 097e27d3d..6d0aa2e61 100644 --- a/include/TGUI/Backend/Font/SDL_ttf/BackendFontSDLttf.hpp +++ b/include/TGUI/Backend/Font/SDL_ttf/BackendFontSDLttf.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp b/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp index 3482bf985..c9bab62b1 100644 --- a/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp +++ b/include/TGUI/Backend/Font/SFML-Graphics/BackendFontSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/GLFW-GLES2.hpp b/include/TGUI/Backend/GLFW-GLES2.hpp index 038a5510b..9f76f80bf 100644 --- a/include/TGUI/Backend/GLFW-GLES2.hpp +++ b/include/TGUI/Backend/GLFW-GLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/GLFW-OpenGL3.hpp b/include/TGUI/Backend/GLFW-OpenGL3.hpp index 3d721a68e..678ec33fc 100644 --- a/include/TGUI/Backend/GLFW-OpenGL3.hpp +++ b/include/TGUI/Backend/GLFW-OpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/BackendRenderTarget.hpp b/include/TGUI/Backend/Renderer/BackendRenderTarget.hpp index f714efa2d..d4bf91b43 100644 --- a/include/TGUI/Backend/Renderer/BackendRenderTarget.hpp +++ b/include/TGUI/Backend/Renderer/BackendRenderTarget.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/BackendRenderer.hpp b/include/TGUI/Backend/Renderer/BackendRenderer.hpp index ae825982a..7d1cd6033 100644 --- a/include/TGUI/Backend/Renderer/BackendRenderer.hpp +++ b/include/TGUI/Backend/Renderer/BackendRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/BackendText.hpp b/include/TGUI/Backend/Renderer/BackendText.hpp index 7bbca024a..bb82ede81 100644 --- a/include/TGUI/Backend/Renderer/BackendText.hpp +++ b/include/TGUI/Backend/Renderer/BackendText.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/BackendTexture.hpp b/include/TGUI/Backend/Renderer/BackendTexture.hpp index 470ae0853..2c2ee576d 100644 --- a/include/TGUI/Backend/Renderer/BackendTexture.hpp +++ b/include/TGUI/Backend/Renderer/BackendTexture.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/GLES2/BackendRenderTargetGLES2.hpp b/include/TGUI/Backend/Renderer/GLES2/BackendRenderTargetGLES2.hpp index 8d403ecfc..416e1f472 100644 --- a/include/TGUI/Backend/Renderer/GLES2/BackendRenderTargetGLES2.hpp +++ b/include/TGUI/Backend/Renderer/GLES2/BackendRenderTargetGLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/GLES2/BackendRendererGLES2.hpp b/include/TGUI/Backend/Renderer/GLES2/BackendRendererGLES2.hpp index bf73115f4..656aa876d 100644 --- a/include/TGUI/Backend/Renderer/GLES2/BackendRendererGLES2.hpp +++ b/include/TGUI/Backend/Renderer/GLES2/BackendRendererGLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/GLES2/BackendTextureGLES2.hpp b/include/TGUI/Backend/Renderer/GLES2/BackendTextureGLES2.hpp index bff513ec9..81f699187 100644 --- a/include/TGUI/Backend/Renderer/GLES2/BackendTextureGLES2.hpp +++ b/include/TGUI/Backend/Renderer/GLES2/BackendTextureGLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/GLES2/CanvasGLES2.hpp b/include/TGUI/Backend/Renderer/GLES2/CanvasGLES2.hpp index 6b297331e..ee9472b9e 100644 --- a/include/TGUI/Backend/Renderer/GLES2/CanvasGLES2.hpp +++ b/include/TGUI/Backend/Renderer/GLES2/CanvasGLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/OpenGL.hpp b/include/TGUI/Backend/Renderer/OpenGL.hpp index f45b685e7..a2bbc889a 100644 --- a/include/TGUI/Backend/Renderer/OpenGL.hpp +++ b/include/TGUI/Backend/Renderer/OpenGL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.hpp b/include/TGUI/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.hpp index 50265ff5f..e271750ef 100644 --- a/include/TGUI/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.hpp +++ b/include/TGUI/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.hpp b/include/TGUI/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.hpp index db4ddba3e..f2dafa9bb 100644 --- a/include/TGUI/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.hpp +++ b/include/TGUI/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.hpp b/include/TGUI/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.hpp index 800eb1b6c..504c84123 100644 --- a/include/TGUI/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.hpp +++ b/include/TGUI/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/OpenGL3/CanvasOpenGL3.hpp b/include/TGUI/Backend/Renderer/OpenGL3/CanvasOpenGL3.hpp index 9ceb9bbac..5c5e821c1 100644 --- a/include/TGUI/Backend/Renderer/OpenGL3/CanvasOpenGL3.hpp +++ b/include/TGUI/Backend/Renderer/OpenGL3/CanvasOpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/Raylib/BackendRenderTargetRaylib.hpp b/include/TGUI/Backend/Renderer/Raylib/BackendRenderTargetRaylib.hpp index 186ec440d..73695db04 100644 --- a/include/TGUI/Backend/Renderer/Raylib/BackendRenderTargetRaylib.hpp +++ b/include/TGUI/Backend/Renderer/Raylib/BackendRenderTargetRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/Raylib/BackendRendererRaylib.hpp b/include/TGUI/Backend/Renderer/Raylib/BackendRendererRaylib.hpp index e19d41a24..fd3c61215 100644 --- a/include/TGUI/Backend/Renderer/Raylib/BackendRendererRaylib.hpp +++ b/include/TGUI/Backend/Renderer/Raylib/BackendRendererRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/Raylib/BackendTextureRaylib.hpp b/include/TGUI/Backend/Renderer/Raylib/BackendTextureRaylib.hpp index 549b68f6b..124dfb3cf 100644 --- a/include/TGUI/Backend/Renderer/Raylib/BackendTextureRaylib.hpp +++ b/include/TGUI/Backend/Renderer/Raylib/BackendTextureRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/Raylib/CanvasRaylib.hpp b/include/TGUI/Backend/Renderer/Raylib/CanvasRaylib.hpp index a98914d3a..d9df7df46 100644 --- a/include/TGUI/Backend/Renderer/Raylib/CanvasRaylib.hpp +++ b/include/TGUI/Backend/Renderer/Raylib/CanvasRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.hpp b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.hpp index 65cc00ca3..200c31d0d 100644 --- a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.hpp +++ b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRendererSDL.hpp b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRendererSDL.hpp index d802f0b95..94757d214 100644 --- a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRendererSDL.hpp +++ b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendRendererSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendTextureSDL.hpp b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendTextureSDL.hpp index 168aa5c41..269ff5220 100644 --- a/include/TGUI/Backend/Renderer/SDL_Renderer/BackendTextureSDL.hpp +++ b/include/TGUI/Backend/Renderer/SDL_Renderer/BackendTextureSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SDL_Renderer/CanvasSDL.hpp b/include/TGUI/Backend/Renderer/SDL_Renderer/CanvasSDL.hpp index ebcff0487..59570b0f4 100644 --- a/include/TGUI/Backend/Renderer/SDL_Renderer/CanvasSDL.hpp +++ b/include/TGUI/Backend/Renderer/SDL_Renderer/CanvasSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.hpp index f270e5c18..5e5555652 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRendererSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRendererSFML.hpp index d1898e002..ecdf6abb9 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRendererSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendRendererSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendTextureSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendTextureSFML.hpp index 50fef6be7..554fed2f3 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/BackendTextureSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/BackendTextureSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp index c46a1dd44..8bebc114f 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SDL-GLES2.hpp b/include/TGUI/Backend/SDL-GLES2.hpp index 32bc76f52..8ffd4c79c 100644 --- a/include/TGUI/Backend/SDL-GLES2.hpp +++ b/include/TGUI/Backend/SDL-GLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SDL-OpenGL3.hpp b/include/TGUI/Backend/SDL-OpenGL3.hpp index a926225f2..6621a93bf 100644 --- a/include/TGUI/Backend/SDL-OpenGL3.hpp +++ b/include/TGUI/Backend/SDL-OpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SDL-Renderer.hpp b/include/TGUI/Backend/SDL-Renderer.hpp index 142b04175..047fdc2bd 100644 --- a/include/TGUI/Backend/SDL-Renderer.hpp +++ b/include/TGUI/Backend/SDL-Renderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SDL-TTF-GLES2.hpp b/include/TGUI/Backend/SDL-TTF-GLES2.hpp index 808fc0171..82a5da7e2 100644 --- a/include/TGUI/Backend/SDL-TTF-GLES2.hpp +++ b/include/TGUI/Backend/SDL-TTF-GLES2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SDL-TTF-OpenGL3.hpp b/include/TGUI/Backend/SDL-TTF-OpenGL3.hpp index f64329c35..30ba9d1db 100644 --- a/include/TGUI/Backend/SDL-TTF-OpenGL3.hpp +++ b/include/TGUI/Backend/SDL-TTF-OpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SFML-Graphics.hpp b/include/TGUI/Backend/SFML-Graphics.hpp index adb8bcd3a..e90501fa1 100644 --- a/include/TGUI/Backend/SFML-Graphics.hpp +++ b/include/TGUI/Backend/SFML-Graphics.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/SFML-OpenGL3.hpp b/include/TGUI/Backend/SFML-OpenGL3.hpp index e651bef74..d44118353 100644 --- a/include/TGUI/Backend/SFML-OpenGL3.hpp +++ b/include/TGUI/Backend/SFML-OpenGL3.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/Backend.hpp b/include/TGUI/Backend/Window/Backend.hpp index baea3d233..d8935f54d 100644 --- a/include/TGUI/Backend/Window/Backend.hpp +++ b/include/TGUI/Backend/Window/Backend.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/BackendGui.hpp b/include/TGUI/Backend/Window/BackendGui.hpp index 81e203c12..bba2b7dc7 100644 --- a/include/TGUI/Backend/Window/BackendGui.hpp +++ b/include/TGUI/Backend/Window/BackendGui.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/GLFW/BackendGLFW.hpp b/include/TGUI/Backend/Window/GLFW/BackendGLFW.hpp index b931d1ab7..abfc87b38 100644 --- a/include/TGUI/Backend/Window/GLFW/BackendGLFW.hpp +++ b/include/TGUI/Backend/Window/GLFW/BackendGLFW.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/GLFW/BackendGuiGLFW.hpp b/include/TGUI/Backend/Window/GLFW/BackendGuiGLFW.hpp index 9cd83dcd5..8b92a7417 100644 --- a/include/TGUI/Backend/Window/GLFW/BackendGuiGLFW.hpp +++ b/include/TGUI/Backend/Window/GLFW/BackendGuiGLFW.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/Raylib/BackendGuiRaylib.hpp b/include/TGUI/Backend/Window/Raylib/BackendGuiRaylib.hpp index 9aacdf05c..4baa5f132 100644 --- a/include/TGUI/Backend/Window/Raylib/BackendGuiRaylib.hpp +++ b/include/TGUI/Backend/Window/Raylib/BackendGuiRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/Raylib/BackendRaylib.hpp b/include/TGUI/Backend/Window/Raylib/BackendRaylib.hpp index 80a497941..b11b6cb39 100644 --- a/include/TGUI/Backend/Window/Raylib/BackendRaylib.hpp +++ b/include/TGUI/Backend/Window/Raylib/BackendRaylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/SDL/BackendGuiSDL.hpp b/include/TGUI/Backend/Window/SDL/BackendGuiSDL.hpp index 11a22fc45..7acf1cce6 100644 --- a/include/TGUI/Backend/Window/SDL/BackendGuiSDL.hpp +++ b/include/TGUI/Backend/Window/SDL/BackendGuiSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/SDL/BackendSDL.hpp b/include/TGUI/Backend/Window/SDL/BackendSDL.hpp index c9b46097d..d9f22ad15 100644 --- a/include/TGUI/Backend/Window/SDL/BackendSDL.hpp +++ b/include/TGUI/Backend/Window/SDL/BackendSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp index 149644f02..d127cfbd0 100644 --- a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp +++ b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/Window/SFML/BackendSFML.hpp b/include/TGUI/Backend/Window/SFML/BackendSFML.hpp index edcf5450c..e331132ea 100644 --- a/include/TGUI/Backend/Window/SFML/BackendSFML.hpp +++ b/include/TGUI/Backend/Window/SFML/BackendSFML.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Backend/raylib.hpp b/include/TGUI/Backend/raylib.hpp index bcc36fe6f..0ebc23754 100644 --- a/include/TGUI/Backend/raylib.hpp +++ b/include/TGUI/Backend/raylib.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Base64.hpp b/include/TGUI/Base64.hpp index 098b6f777..2fdfd74b8 100644 --- a/include/TGUI/Base64.hpp +++ b/include/TGUI/Base64.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Color.hpp b/include/TGUI/Color.hpp index cae74d47f..767958604 100644 --- a/include/TGUI/Color.hpp +++ b/include/TGUI/Color.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Components.hpp b/include/TGUI/Components.hpp index 9fb06f5d2..6c57b7ba6 100644 --- a/include/TGUI/Components.hpp +++ b/include/TGUI/Components.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Config.hpp.in b/include/TGUI/Config.hpp.in index 1488892ec..fdaff56ec 100644 --- a/include/TGUI/Config.hpp.in +++ b/include/TGUI/Config.hpp.in @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Container.hpp b/include/TGUI/Container.hpp index d715f98e1..32177d67a 100644 --- a/include/TGUI/Container.hpp +++ b/include/TGUI/Container.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/CopiedSharedPtr.hpp b/include/TGUI/CopiedSharedPtr.hpp index 068cd6a3a..7b0cd81de 100644 --- a/include/TGUI/CopiedSharedPtr.hpp +++ b/include/TGUI/CopiedSharedPtr.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Core.hpp b/include/TGUI/Core.hpp index a32f45cf1..506d206a0 100644 --- a/include/TGUI/Core.hpp +++ b/include/TGUI/Core.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Cursor.hpp b/include/TGUI/Cursor.hpp index 32c9325cf..e5162a0df 100644 --- a/include/TGUI/Cursor.hpp +++ b/include/TGUI/Cursor.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/CustomWidgetForBindings.hpp b/include/TGUI/CustomWidgetForBindings.hpp index 1606f6e59..d37c7c35c 100644 --- a/include/TGUI/CustomWidgetForBindings.hpp +++ b/include/TGUI/CustomWidgetForBindings.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/DefaultBackendWindow.hpp b/include/TGUI/DefaultBackendWindow.hpp index 08577a033..776a21bf1 100644 --- a/include/TGUI/DefaultBackendWindow.hpp +++ b/include/TGUI/DefaultBackendWindow.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Duration.hpp b/include/TGUI/Duration.hpp index bdcea630c..ba4ef7e03 100644 --- a/include/TGUI/Duration.hpp +++ b/include/TGUI/Duration.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Event.hpp b/include/TGUI/Event.hpp index a9d25c805..ea7ddb66f 100644 --- a/include/TGUI/Event.hpp +++ b/include/TGUI/Event.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Exception.hpp b/include/TGUI/Exception.hpp index b5daa9076..df6da2352 100644 --- a/include/TGUI/Exception.hpp +++ b/include/TGUI/Exception.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/FileDialogIconLoader.hpp b/include/TGUI/FileDialogIconLoader.hpp index c4b8978cf..cf3e9c99d 100644 --- a/include/TGUI/FileDialogIconLoader.hpp +++ b/include/TGUI/FileDialogIconLoader.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Filesystem.hpp b/include/TGUI/Filesystem.hpp index 85bc6385d..4344dd5ee 100644 --- a/include/TGUI/Filesystem.hpp +++ b/include/TGUI/Filesystem.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Font.hpp b/include/TGUI/Font.hpp index f70f32bd3..71bc772c5 100644 --- a/include/TGUI/Font.hpp +++ b/include/TGUI/Font.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Global.hpp b/include/TGUI/Global.hpp index bf78c88a0..21c1c5850 100644 --- a/include/TGUI/Global.hpp +++ b/include/TGUI/Global.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Keyboard.hpp b/include/TGUI/Keyboard.hpp index f1f81e77a..0ef8532f8 100644 --- a/include/TGUI/Keyboard.hpp +++ b/include/TGUI/Keyboard.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Layout.hpp b/include/TGUI/Layout.hpp index 7a8ee99a8..370070e23 100644 --- a/include/TGUI/Layout.hpp +++ b/include/TGUI/Layout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/DataIO.hpp b/include/TGUI/Loading/DataIO.hpp index 790aecebb..129be030a 100644 --- a/include/TGUI/Loading/DataIO.hpp +++ b/include/TGUI/Loading/DataIO.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/Deserializer.hpp b/include/TGUI/Loading/Deserializer.hpp index eb0d7bc9a..71cf732a1 100644 --- a/include/TGUI/Loading/Deserializer.hpp +++ b/include/TGUI/Loading/Deserializer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/ImageLoader.hpp b/include/TGUI/Loading/ImageLoader.hpp index 0fbc1d2a1..12f48e305 100644 --- a/include/TGUI/Loading/ImageLoader.hpp +++ b/include/TGUI/Loading/ImageLoader.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/Serializer.hpp b/include/TGUI/Loading/Serializer.hpp index b2f7d6b08..5d5746a9a 100644 --- a/include/TGUI/Loading/Serializer.hpp +++ b/include/TGUI/Loading/Serializer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/Theme.hpp b/include/TGUI/Loading/Theme.hpp index 2bf39450b..419cc57bc 100644 --- a/include/TGUI/Loading/Theme.hpp +++ b/include/TGUI/Loading/Theme.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/ThemeLoader.hpp b/include/TGUI/Loading/ThemeLoader.hpp index fc33d2151..86e752ca7 100644 --- a/include/TGUI/Loading/ThemeLoader.hpp +++ b/include/TGUI/Loading/ThemeLoader.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Loading/WidgetFactory.hpp b/include/TGUI/Loading/WidgetFactory.hpp index 5fcbdc89d..319232ca1 100644 --- a/include/TGUI/Loading/WidgetFactory.hpp +++ b/include/TGUI/Loading/WidgetFactory.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/ObjectConverter.hpp b/include/TGUI/ObjectConverter.hpp index 5013f045d..93731862e 100644 --- a/include/TGUI/ObjectConverter.hpp +++ b/include/TGUI/ObjectConverter.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Optional.hpp b/include/TGUI/Optional.hpp index df72929b1..e1e5d94c4 100644 --- a/include/TGUI/Optional.hpp +++ b/include/TGUI/Optional.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Outline.hpp b/include/TGUI/Outline.hpp index 5195c8ed7..b6712af8a 100644 --- a/include/TGUI/Outline.hpp +++ b/include/TGUI/Outline.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Rect.hpp b/include/TGUI/Rect.hpp index e12dc13a6..0d4e11438 100644 --- a/include/TGUI/Rect.hpp +++ b/include/TGUI/Rect.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/RelFloatRect.hpp b/include/TGUI/RelFloatRect.hpp index 635764f92..5911825c3 100644 --- a/include/TGUI/RelFloatRect.hpp +++ b/include/TGUI/RelFloatRect.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/RenderStates.hpp b/include/TGUI/RenderStates.hpp index 7d2815c27..ebe4a394f 100644 --- a/include/TGUI/RenderStates.hpp +++ b/include/TGUI/RenderStates.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/RendererDefines.hpp b/include/TGUI/RendererDefines.hpp index 374bdf668..ec8c2afcd 100644 --- a/include/TGUI/RendererDefines.hpp +++ b/include/TGUI/RendererDefines.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/BoxLayoutRenderer.hpp b/include/TGUI/Renderers/BoxLayoutRenderer.hpp index b70c77417..9fc5abc6f 100644 --- a/include/TGUI/Renderers/BoxLayoutRenderer.hpp +++ b/include/TGUI/Renderers/BoxLayoutRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ButtonRenderer.hpp b/include/TGUI/Renderers/ButtonRenderer.hpp index 07bbc80cd..b3bdbfe70 100644 --- a/include/TGUI/Renderers/ButtonRenderer.hpp +++ b/include/TGUI/Renderers/ButtonRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ChatBoxRenderer.hpp b/include/TGUI/Renderers/ChatBoxRenderer.hpp index 280975ec6..b3c67fa5b 100644 --- a/include/TGUI/Renderers/ChatBoxRenderer.hpp +++ b/include/TGUI/Renderers/ChatBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/CheckBoxRenderer.hpp b/include/TGUI/Renderers/CheckBoxRenderer.hpp index e631d103f..f54430479 100644 --- a/include/TGUI/Renderers/CheckBoxRenderer.hpp +++ b/include/TGUI/Renderers/CheckBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ChildWindowRenderer.hpp b/include/TGUI/Renderers/ChildWindowRenderer.hpp index 428b70ee0..2e44a387e 100644 --- a/include/TGUI/Renderers/ChildWindowRenderer.hpp +++ b/include/TGUI/Renderers/ChildWindowRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ColorPickerRenderer.hpp b/include/TGUI/Renderers/ColorPickerRenderer.hpp index 75f6bc025..ad7fd3d8a 100644 --- a/include/TGUI/Renderers/ColorPickerRenderer.hpp +++ b/include/TGUI/Renderers/ColorPickerRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ComboBoxRenderer.hpp b/include/TGUI/Renderers/ComboBoxRenderer.hpp index 1ca1c3437..a120f9148 100644 --- a/include/TGUI/Renderers/ComboBoxRenderer.hpp +++ b/include/TGUI/Renderers/ComboBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/EditBoxRenderer.hpp b/include/TGUI/Renderers/EditBoxRenderer.hpp index 1bd70ad58..3ec54e086 100644 --- a/include/TGUI/Renderers/EditBoxRenderer.hpp +++ b/include/TGUI/Renderers/EditBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/FileDialogRenderer.hpp b/include/TGUI/Renderers/FileDialogRenderer.hpp index bb2c09e87..e99e2895c 100644 --- a/include/TGUI/Renderers/FileDialogRenderer.hpp +++ b/include/TGUI/Renderers/FileDialogRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/GroupRenderer.hpp b/include/TGUI/Renderers/GroupRenderer.hpp index bd5e7ee79..03a399170 100644 --- a/include/TGUI/Renderers/GroupRenderer.hpp +++ b/include/TGUI/Renderers/GroupRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/KnobRenderer.hpp b/include/TGUI/Renderers/KnobRenderer.hpp index aaa02591a..cd13cbc38 100644 --- a/include/TGUI/Renderers/KnobRenderer.hpp +++ b/include/TGUI/Renderers/KnobRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/LabelRenderer.hpp b/include/TGUI/Renderers/LabelRenderer.hpp index ba26914b1..a61197819 100644 --- a/include/TGUI/Renderers/LabelRenderer.hpp +++ b/include/TGUI/Renderers/LabelRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ListBoxRenderer.hpp b/include/TGUI/Renderers/ListBoxRenderer.hpp index 7dcf773da..e674ac210 100644 --- a/include/TGUI/Renderers/ListBoxRenderer.hpp +++ b/include/TGUI/Renderers/ListBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ListViewRenderer.hpp b/include/TGUI/Renderers/ListViewRenderer.hpp index 5743399ef..e350939a7 100644 --- a/include/TGUI/Renderers/ListViewRenderer.hpp +++ b/include/TGUI/Renderers/ListViewRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/MessageBoxRenderer.hpp b/include/TGUI/Renderers/MessageBoxRenderer.hpp index 922a976b4..adfb333e3 100644 --- a/include/TGUI/Renderers/MessageBoxRenderer.hpp +++ b/include/TGUI/Renderers/MessageBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/PanelListBoxRenderer.hpp b/include/TGUI/Renderers/PanelListBoxRenderer.hpp index 1ea206d98..0fdb7f76c 100644 --- a/include/TGUI/Renderers/PanelListBoxRenderer.hpp +++ b/include/TGUI/Renderers/PanelListBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/PanelRenderer.hpp b/include/TGUI/Renderers/PanelRenderer.hpp index 484e226ac..f335b71db 100644 --- a/include/TGUI/Renderers/PanelRenderer.hpp +++ b/include/TGUI/Renderers/PanelRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/PictureRenderer.hpp b/include/TGUI/Renderers/PictureRenderer.hpp index 13c788bb1..3e6750ae7 100644 --- a/include/TGUI/Renderers/PictureRenderer.hpp +++ b/include/TGUI/Renderers/PictureRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ProgressBarRenderer.hpp b/include/TGUI/Renderers/ProgressBarRenderer.hpp index d156e71a7..fa837f984 100644 --- a/include/TGUI/Renderers/ProgressBarRenderer.hpp +++ b/include/TGUI/Renderers/ProgressBarRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/RadioButtonRenderer.hpp b/include/TGUI/Renderers/RadioButtonRenderer.hpp index 628899858..0b894e3a6 100644 --- a/include/TGUI/Renderers/RadioButtonRenderer.hpp +++ b/include/TGUI/Renderers/RadioButtonRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/RangeSliderRenderer.hpp b/include/TGUI/Renderers/RangeSliderRenderer.hpp index b4dda200f..973101992 100644 --- a/include/TGUI/Renderers/RangeSliderRenderer.hpp +++ b/include/TGUI/Renderers/RangeSliderRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ScrollablePanelRenderer.hpp b/include/TGUI/Renderers/ScrollablePanelRenderer.hpp index 8445c2c7c..50fc678e2 100644 --- a/include/TGUI/Renderers/ScrollablePanelRenderer.hpp +++ b/include/TGUI/Renderers/ScrollablePanelRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/ScrollbarRenderer.hpp b/include/TGUI/Renderers/ScrollbarRenderer.hpp index 7cf9f3288..93f22ad40 100644 --- a/include/TGUI/Renderers/ScrollbarRenderer.hpp +++ b/include/TGUI/Renderers/ScrollbarRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/SeparatorLineRenderer.hpp b/include/TGUI/Renderers/SeparatorLineRenderer.hpp index 7e2eb9155..54f9e0cf7 100644 --- a/include/TGUI/Renderers/SeparatorLineRenderer.hpp +++ b/include/TGUI/Renderers/SeparatorLineRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/SliderRenderer.hpp b/include/TGUI/Renderers/SliderRenderer.hpp index 471f32f96..2a4b1e10b 100644 --- a/include/TGUI/Renderers/SliderRenderer.hpp +++ b/include/TGUI/Renderers/SliderRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/SpinButtonRenderer.hpp b/include/TGUI/Renderers/SpinButtonRenderer.hpp index 5d2f5fca8..3df5f2239 100644 --- a/include/TGUI/Renderers/SpinButtonRenderer.hpp +++ b/include/TGUI/Renderers/SpinButtonRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/SplitContainerRenderer.hpp b/include/TGUI/Renderers/SplitContainerRenderer.hpp index 145625587..ff14bc813 100644 --- a/include/TGUI/Renderers/SplitContainerRenderer.hpp +++ b/include/TGUI/Renderers/SplitContainerRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/TabsRenderer.hpp b/include/TGUI/Renderers/TabsRenderer.hpp index d6c0371b0..a0ddd01d6 100644 --- a/include/TGUI/Renderers/TabsRenderer.hpp +++ b/include/TGUI/Renderers/TabsRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/TextAreaRenderer.hpp b/include/TGUI/Renderers/TextAreaRenderer.hpp index 01e82dd98..a7375e89b 100644 --- a/include/TGUI/Renderers/TextAreaRenderer.hpp +++ b/include/TGUI/Renderers/TextAreaRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/TextBoxRenderer.hpp b/include/TGUI/Renderers/TextBoxRenderer.hpp index 2e3311b53..9af42eb04 100644 --- a/include/TGUI/Renderers/TextBoxRenderer.hpp +++ b/include/TGUI/Renderers/TextBoxRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/TreeViewRenderer.hpp b/include/TGUI/Renderers/TreeViewRenderer.hpp index 6e36ff1de..2e62e51ab 100644 --- a/include/TGUI/Renderers/TreeViewRenderer.hpp +++ b/include/TGUI/Renderers/TreeViewRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Renderers/WidgetRenderer.hpp b/include/TGUI/Renderers/WidgetRenderer.hpp index fdeb80a03..764e7c4a3 100644 --- a/include/TGUI/Renderers/WidgetRenderer.hpp +++ b/include/TGUI/Renderers/WidgetRenderer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Signal.hpp b/include/TGUI/Signal.hpp index d2e30f496..de4429872 100644 --- a/include/TGUI/Signal.hpp +++ b/include/TGUI/Signal.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/SignalManager.hpp b/include/TGUI/SignalManager.hpp index b7eeeb90f..4afe4b445 100644 --- a/include/TGUI/SignalManager.hpp +++ b/include/TGUI/SignalManager.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Sprite.hpp b/include/TGUI/Sprite.hpp index 8ef660b7a..819e76cad 100644 --- a/include/TGUI/Sprite.hpp +++ b/include/TGUI/Sprite.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/String.hpp b/include/TGUI/String.hpp index 8c745939a..cad01747e 100644 --- a/include/TGUI/String.hpp +++ b/include/TGUI/String.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/StringView.hpp b/include/TGUI/StringView.hpp index c28c8502f..48180ab87 100644 --- a/include/TGUI/StringView.hpp +++ b/include/TGUI/StringView.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/SubwidgetContainer.hpp b/include/TGUI/SubwidgetContainer.hpp index fdf9b9bc3..ba090d088 100644 --- a/include/TGUI/SubwidgetContainer.hpp +++ b/include/TGUI/SubwidgetContainer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/SvgImage.hpp b/include/TGUI/SvgImage.hpp index 79aada0de..47bc5f290 100644 --- a/include/TGUI/SvgImage.hpp +++ b/include/TGUI/SvgImage.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/TGUI.hpp b/include/TGUI/TGUI.hpp index e70a81e5d..0601765e3 100644 --- a/include/TGUI/TGUI.hpp +++ b/include/TGUI/TGUI.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Text.hpp b/include/TGUI/Text.hpp index e362be2c1..d8f3b131f 100644 --- a/include/TGUI/Text.hpp +++ b/include/TGUI/Text.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/TextStyle.hpp b/include/TGUI/TextStyle.hpp index 766cb4609..ab04e939f 100644 --- a/include/TGUI/TextStyle.hpp +++ b/include/TGUI/TextStyle.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Texture.hpp b/include/TGUI/Texture.hpp index e71c3b57e..03b4d19a5 100644 --- a/include/TGUI/Texture.hpp +++ b/include/TGUI/Texture.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/TextureData.hpp b/include/TGUI/TextureData.hpp index 18532dadb..e1f18f322 100644 --- a/include/TGUI/TextureData.hpp +++ b/include/TGUI/TextureData.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/TextureManager.hpp b/include/TGUI/TextureManager.hpp index e0691dd32..df17b7295 100644 --- a/include/TGUI/TextureManager.hpp +++ b/include/TGUI/TextureManager.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Timer.hpp b/include/TGUI/Timer.hpp index 2fb55e755..02c65d4c9 100644 --- a/include/TGUI/Timer.hpp +++ b/include/TGUI/Timer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/ToolTip.hpp b/include/TGUI/ToolTip.hpp index b7e192be3..09d3e51d5 100644 --- a/include/TGUI/ToolTip.hpp +++ b/include/TGUI/ToolTip.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Transform.hpp b/include/TGUI/Transform.hpp index 7ba0a69f2..b932f9dce 100644 --- a/include/TGUI/Transform.hpp +++ b/include/TGUI/Transform.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/TwoFingerScrollDetect.hpp b/include/TGUI/TwoFingerScrollDetect.hpp index 42241b23e..3d3116e5b 100644 --- a/include/TGUI/TwoFingerScrollDetect.hpp +++ b/include/TGUI/TwoFingerScrollDetect.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Utf.hpp b/include/TGUI/Utf.hpp index c374a06dd..758cda568 100644 --- a/include/TGUI/Utf.hpp +++ b/include/TGUI/Utf.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Variant.hpp b/include/TGUI/Variant.hpp index 47970ddda..7765698e8 100644 --- a/include/TGUI/Variant.hpp +++ b/include/TGUI/Variant.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Vector2.hpp b/include/TGUI/Vector2.hpp index 282b8badd..ebb43d0c7 100644 --- a/include/TGUI/Vector2.hpp +++ b/include/TGUI/Vector2.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Vertex.hpp b/include/TGUI/Vertex.hpp index 68ece44eb..5f1b3aeea 100644 --- a/include/TGUI/Vertex.hpp +++ b/include/TGUI/Vertex.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widget.hpp b/include/TGUI/Widget.hpp index cce08060a..be08f69b5 100644 --- a/include/TGUI/Widget.hpp +++ b/include/TGUI/Widget.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/BitmapButton.hpp b/include/TGUI/Widgets/BitmapButton.hpp index 11a5276aa..2b847f6f8 100644 --- a/include/TGUI/Widgets/BitmapButton.hpp +++ b/include/TGUI/Widgets/BitmapButton.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/BoxLayout.hpp b/include/TGUI/Widgets/BoxLayout.hpp index d07b20d64..fb4df3254 100644 --- a/include/TGUI/Widgets/BoxLayout.hpp +++ b/include/TGUI/Widgets/BoxLayout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/BoxLayoutRatios.hpp b/include/TGUI/Widgets/BoxLayoutRatios.hpp index 848ea2635..664422fc9 100644 --- a/include/TGUI/Widgets/BoxLayoutRatios.hpp +++ b/include/TGUI/Widgets/BoxLayoutRatios.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Button.hpp b/include/TGUI/Widgets/Button.hpp index 099226fe6..7e55c2fd6 100644 --- a/include/TGUI/Widgets/Button.hpp +++ b/include/TGUI/Widgets/Button.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ButtonBase.hpp b/include/TGUI/Widgets/ButtonBase.hpp index 2b9ffea09..7cd4b4bd2 100644 --- a/include/TGUI/Widgets/ButtonBase.hpp +++ b/include/TGUI/Widgets/ButtonBase.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/CanvasBase.hpp b/include/TGUI/Widgets/CanvasBase.hpp index e91cec11d..b310aa00e 100644 --- a/include/TGUI/Widgets/CanvasBase.hpp +++ b/include/TGUI/Widgets/CanvasBase.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ChatBox.hpp b/include/TGUI/Widgets/ChatBox.hpp index 4cf5fe4a3..a37385742 100644 --- a/include/TGUI/Widgets/ChatBox.hpp +++ b/include/TGUI/Widgets/ChatBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/CheckBox.hpp b/include/TGUI/Widgets/CheckBox.hpp index 7be7a385f..023ae8a2c 100644 --- a/include/TGUI/Widgets/CheckBox.hpp +++ b/include/TGUI/Widgets/CheckBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ChildWindow.hpp b/include/TGUI/Widgets/ChildWindow.hpp index 29d7b7402..a0cf79667 100644 --- a/include/TGUI/Widgets/ChildWindow.hpp +++ b/include/TGUI/Widgets/ChildWindow.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ClickableWidget.hpp b/include/TGUI/Widgets/ClickableWidget.hpp index 58036bde9..10b027c00 100644 --- a/include/TGUI/Widgets/ClickableWidget.hpp +++ b/include/TGUI/Widgets/ClickableWidget.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ColorPicker.hpp b/include/TGUI/Widgets/ColorPicker.hpp index f83aaf3d5..a14187390 100644 --- a/include/TGUI/Widgets/ColorPicker.hpp +++ b/include/TGUI/Widgets/ColorPicker.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ComboBox.hpp b/include/TGUI/Widgets/ComboBox.hpp index d8861e9ae..fff3e0cfd 100644 --- a/include/TGUI/Widgets/ComboBox.hpp +++ b/include/TGUI/Widgets/ComboBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/EditBox.hpp b/include/TGUI/Widgets/EditBox.hpp index 32e820d27..14da45382 100644 --- a/include/TGUI/Widgets/EditBox.hpp +++ b/include/TGUI/Widgets/EditBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/FileDialog.hpp b/include/TGUI/Widgets/FileDialog.hpp index debf28528..e2051a96c 100644 --- a/include/TGUI/Widgets/FileDialog.hpp +++ b/include/TGUI/Widgets/FileDialog.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Grid.hpp b/include/TGUI/Widgets/Grid.hpp index a12830c72..c7bc628c8 100644 --- a/include/TGUI/Widgets/Grid.hpp +++ b/include/TGUI/Widgets/Grid.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Group.hpp b/include/TGUI/Widgets/Group.hpp index e65402264..c5dd39359 100644 --- a/include/TGUI/Widgets/Group.hpp +++ b/include/TGUI/Widgets/Group.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/GrowHorizontalLayout.hpp b/include/TGUI/Widgets/GrowHorizontalLayout.hpp index ca150adf9..3fb6d0e64 100644 --- a/include/TGUI/Widgets/GrowHorizontalLayout.hpp +++ b/include/TGUI/Widgets/GrowHorizontalLayout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/GrowVerticalLayout.hpp b/include/TGUI/Widgets/GrowVerticalLayout.hpp index b3e3217c1..9a7ab5851 100644 --- a/include/TGUI/Widgets/GrowVerticalLayout.hpp +++ b/include/TGUI/Widgets/GrowVerticalLayout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/HorizontalLayout.hpp b/include/TGUI/Widgets/HorizontalLayout.hpp index e65ae21b3..78b05baee 100644 --- a/include/TGUI/Widgets/HorizontalLayout.hpp +++ b/include/TGUI/Widgets/HorizontalLayout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/HorizontalWrap.hpp b/include/TGUI/Widgets/HorizontalWrap.hpp index 3a94881be..fe576f119 100644 --- a/include/TGUI/Widgets/HorizontalWrap.hpp +++ b/include/TGUI/Widgets/HorizontalWrap.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus's Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Knob.hpp b/include/TGUI/Widgets/Knob.hpp index c019873e1..fec385c78 100644 --- a/include/TGUI/Widgets/Knob.hpp +++ b/include/TGUI/Widgets/Knob.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Label.hpp b/include/TGUI/Widgets/Label.hpp index 204efa79a..c0591c4a0 100644 --- a/include/TGUI/Widgets/Label.hpp +++ b/include/TGUI/Widgets/Label.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ListBox.hpp b/include/TGUI/Widgets/ListBox.hpp index bafc7d75e..36a78bf11 100644 --- a/include/TGUI/Widgets/ListBox.hpp +++ b/include/TGUI/Widgets/ListBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ListView.hpp b/include/TGUI/Widgets/ListView.hpp index 39beacbfc..1c4b62021 100644 --- a/include/TGUI/Widgets/ListView.hpp +++ b/include/TGUI/Widgets/ListView.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/MessageBox.hpp b/include/TGUI/Widgets/MessageBox.hpp index 15427138f..d56676702 100644 --- a/include/TGUI/Widgets/MessageBox.hpp +++ b/include/TGUI/Widgets/MessageBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Panel.hpp b/include/TGUI/Widgets/Panel.hpp index 07ed11dbd..3ecc5378e 100644 --- a/include/TGUI/Widgets/Panel.hpp +++ b/include/TGUI/Widgets/Panel.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/PanelListBox.hpp b/include/TGUI/Widgets/PanelListBox.hpp index c21e500f8..dcf4168e3 100644 --- a/include/TGUI/Widgets/PanelListBox.hpp +++ b/include/TGUI/Widgets/PanelListBox.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Picture.hpp b/include/TGUI/Widgets/Picture.hpp index 3745ed2e8..9bd0d8426 100644 --- a/include/TGUI/Widgets/Picture.hpp +++ b/include/TGUI/Widgets/Picture.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ProgressBar.hpp b/include/TGUI/Widgets/ProgressBar.hpp index ac37143b0..a24d8b250 100644 --- a/include/TGUI/Widgets/ProgressBar.hpp +++ b/include/TGUI/Widgets/ProgressBar.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/RadioButton.hpp b/include/TGUI/Widgets/RadioButton.hpp index 6d24d14e3..b700c3e3d 100644 --- a/include/TGUI/Widgets/RadioButton.hpp +++ b/include/TGUI/Widgets/RadioButton.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/RadioButtonGroup.hpp b/include/TGUI/Widgets/RadioButtonGroup.hpp index 842bb3f6c..29113831e 100644 --- a/include/TGUI/Widgets/RadioButtonGroup.hpp +++ b/include/TGUI/Widgets/RadioButtonGroup.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/RangeSlider.hpp b/include/TGUI/Widgets/RangeSlider.hpp index 043502500..3c94329d1 100644 --- a/include/TGUI/Widgets/RangeSlider.hpp +++ b/include/TGUI/Widgets/RangeSlider.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/RichTextLabel.hpp b/include/TGUI/Widgets/RichTextLabel.hpp index 3b4cff784..9a575c394 100644 --- a/include/TGUI/Widgets/RichTextLabel.hpp +++ b/include/TGUI/Widgets/RichTextLabel.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ScrollablePanel.hpp b/include/TGUI/Widgets/ScrollablePanel.hpp index 6d6398e45..c061b703b 100644 --- a/include/TGUI/Widgets/ScrollablePanel.hpp +++ b/include/TGUI/Widgets/ScrollablePanel.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Scrollbar.hpp b/include/TGUI/Widgets/Scrollbar.hpp index 65785f015..260a17f1b 100644 --- a/include/TGUI/Widgets/Scrollbar.hpp +++ b/include/TGUI/Widgets/Scrollbar.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/SeparatorLine.hpp b/include/TGUI/Widgets/SeparatorLine.hpp index c70a21f79..d114b2c0b 100644 --- a/include/TGUI/Widgets/SeparatorLine.hpp +++ b/include/TGUI/Widgets/SeparatorLine.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Slider.hpp b/include/TGUI/Widgets/Slider.hpp index 0358637c1..56702549c 100644 --- a/include/TGUI/Widgets/Slider.hpp +++ b/include/TGUI/Widgets/Slider.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/SpinButton.hpp b/include/TGUI/Widgets/SpinButton.hpp index 02521ba6e..37e22e30b 100644 --- a/include/TGUI/Widgets/SpinButton.hpp +++ b/include/TGUI/Widgets/SpinButton.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/SpinControl.hpp b/include/TGUI/Widgets/SpinControl.hpp index e129f0d30..5b6010666 100644 --- a/include/TGUI/Widgets/SpinControl.hpp +++ b/include/TGUI/Widgets/SpinControl.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/SplitContainer.hpp b/include/TGUI/Widgets/SplitContainer.hpp index c072a1fc3..41cd0a010 100644 --- a/include/TGUI/Widgets/SplitContainer.hpp +++ b/include/TGUI/Widgets/SplitContainer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/TabContainer.hpp b/include/TGUI/Widgets/TabContainer.hpp index a193c6360..90c40e327 100644 --- a/include/TGUI/Widgets/TabContainer.hpp +++ b/include/TGUI/Widgets/TabContainer.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/Tabs.hpp b/include/TGUI/Widgets/Tabs.hpp index 09fda80d2..bfd547d11 100644 --- a/include/TGUI/Widgets/Tabs.hpp +++ b/include/TGUI/Widgets/Tabs.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/TextArea.hpp b/include/TGUI/Widgets/TextArea.hpp index c0c9e2303..dd300c761 100644 --- a/include/TGUI/Widgets/TextArea.hpp +++ b/include/TGUI/Widgets/TextArea.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/ToggleButton.hpp b/include/TGUI/Widgets/ToggleButton.hpp index df8e9a4cf..521490cf9 100644 --- a/include/TGUI/Widgets/ToggleButton.hpp +++ b/include/TGUI/Widgets/ToggleButton.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/TreeView.hpp b/include/TGUI/Widgets/TreeView.hpp index 037465575..4d46b1b1d 100644 --- a/include/TGUI/Widgets/TreeView.hpp +++ b/include/TGUI/Widgets/TreeView.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/Widgets/VerticalLayout.hpp b/include/TGUI/Widgets/VerticalLayout.hpp index 4dcb6a2b5..b3a097126 100644 --- a/include/TGUI/Widgets/VerticalLayout.hpp +++ b/include/TGUI/Widgets/VerticalLayout.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/WindowsIMM.hpp b/include/TGUI/WindowsIMM.hpp index 425294555..c89b46f8b 100644 --- a/include/TGUI/WindowsIMM.hpp +++ b/include/TGUI/WindowsIMM.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/extlibs/IncludeNanoSVG.hpp b/include/TGUI/extlibs/IncludeNanoSVG.hpp index 6c3c55071..cc9e1922e 100644 --- a/include/TGUI/extlibs/IncludeNanoSVG.hpp +++ b/include/TGUI/extlibs/IncludeNanoSVG.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/extlibs/IncludeSDL.hpp b/include/TGUI/extlibs/IncludeSDL.hpp index e2170649e..7c815747e 100644 --- a/include/TGUI/extlibs/IncludeSDL.hpp +++ b/include/TGUI/extlibs/IncludeSDL.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/extlibs/IncludeStbImage.hpp b/include/TGUI/extlibs/IncludeStbImage.hpp index 9acb855d6..57fe667f5 100644 --- a/include/TGUI/extlibs/IncludeStbImage.hpp +++ b/include/TGUI/extlibs/IncludeStbImage.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/extlibs/IncludeStbImageWrite.hpp b/include/TGUI/extlibs/IncludeStbImageWrite.hpp index a836f9022..09ab16c72 100644 --- a/include/TGUI/extlibs/IncludeStbImageWrite.hpp +++ b/include/TGUI/extlibs/IncludeStbImageWrite.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/include/TGUI/extlibs/IncludeWindows.hpp b/include/TGUI/extlibs/IncludeWindows.hpp index 1ea9c115e..01e79031d 100644 --- a/include/TGUI/extlibs/IncludeWindows.hpp +++ b/include/TGUI/extlibs/IncludeWindows.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/license.txt b/license.txt index b780dca42..2a608a1bb 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2012-2024 Bruno Van de Velde - vdv_b@tgui.eu +Copyright (c) 2012-2025 Bruno Van de Velde - vdv_b@tgui.eu This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held diff --git a/src/Animation.cpp b/src/Animation.cpp index cdf2c7af6..207b6fac5 100644 --- a/src/Animation.cpp +++ b/src/Animation.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/CMakeLists.txt b/src/Backend/CMakeLists.txt index 5ed1d0334..ec15d24f0 100644 --- a/src/Backend/CMakeLists.txt +++ b/src/Backend/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Font/BackendFont.cpp b/src/Backend/Font/BackendFont.cpp index da4f7d59e..b4ccefe5a 100644 --- a/src/Backend/Font/BackendFont.cpp +++ b/src/Backend/Font/BackendFont.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Font/FreeType/BackendFontFreeType.cpp b/src/Backend/Font/FreeType/BackendFontFreeType.cpp index e2c576378..4a2508c49 100644 --- a/src/Backend/Font/FreeType/BackendFontFreeType.cpp +++ b/src/Backend/Font/FreeType/BackendFontFreeType.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Font/Raylib/BackendFontRaylib.cpp b/src/Backend/Font/Raylib/BackendFontRaylib.cpp index 037c0ba36..639e93608 100644 --- a/src/Backend/Font/Raylib/BackendFontRaylib.cpp +++ b/src/Backend/Font/Raylib/BackendFontRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp index 97ae87ad4..48ef74a93 100644 --- a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp +++ b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp index 2bf87040b..fec91cb95 100644 --- a/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp +++ b/src/Backend/Font/SFML-Graphics/BackendFontSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/GLFW-GLES2.cpp b/src/Backend/GLFW-GLES2.cpp index b0b395ffb..c115cfc3b 100644 --- a/src/Backend/GLFW-GLES2.cpp +++ b/src/Backend/GLFW-GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/GLFW-OpenGL3.cpp b/src/Backend/GLFW-OpenGL3.cpp index 17f02f4d9..8d62c2ba9 100644 --- a/src/Backend/GLFW-OpenGL3.cpp +++ b/src/Backend/GLFW-OpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/BackendRenderTarget.cpp b/src/Backend/Renderer/BackendRenderTarget.cpp index 35f6f01d9..394f97188 100644 --- a/src/Backend/Renderer/BackendRenderTarget.cpp +++ b/src/Backend/Renderer/BackendRenderTarget.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/BackendText.cpp b/src/Backend/Renderer/BackendText.cpp index 7609f2a22..f01bdc886 100644 --- a/src/Backend/Renderer/BackendText.cpp +++ b/src/Backend/Renderer/BackendText.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/BackendTexture.cpp b/src/Backend/Renderer/BackendTexture.cpp index 9012abe24..f3ed0d899 100644 --- a/src/Backend/Renderer/BackendTexture.cpp +++ b/src/Backend/Renderer/BackendTexture.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/GLES2/BackendRenderTargetGLES2.cpp b/src/Backend/Renderer/GLES2/BackendRenderTargetGLES2.cpp index a114e3968..b83088dbc 100644 --- a/src/Backend/Renderer/GLES2/BackendRenderTargetGLES2.cpp +++ b/src/Backend/Renderer/GLES2/BackendRenderTargetGLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/GLES2/BackendRendererGLES2.cpp b/src/Backend/Renderer/GLES2/BackendRendererGLES2.cpp index ec04e721b..6841cc070 100644 --- a/src/Backend/Renderer/GLES2/BackendRendererGLES2.cpp +++ b/src/Backend/Renderer/GLES2/BackendRendererGLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/GLES2/BackendTextureGLES2.cpp b/src/Backend/Renderer/GLES2/BackendTextureGLES2.cpp index 8779d3d51..34fceb833 100644 --- a/src/Backend/Renderer/GLES2/BackendTextureGLES2.cpp +++ b/src/Backend/Renderer/GLES2/BackendTextureGLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/GLES2/CanvasGLES2.cpp b/src/Backend/Renderer/GLES2/CanvasGLES2.cpp index 2ccda2479..3e4da739f 100644 --- a/src/Backend/Renderer/GLES2/CanvasGLES2.cpp +++ b/src/Backend/Renderer/GLES2/CanvasGLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL.cpp b/src/Backend/Renderer/OpenGL.cpp index 2dfd7f349..25326a684 100644 --- a/src/Backend/Renderer/OpenGL.cpp +++ b/src/Backend/Renderer/OpenGL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL.cppm b/src/Backend/Renderer/OpenGL.cppm index 5962f6c58..713a5f0df 100644 --- a/src/Backend/Renderer/OpenGL.cppm +++ b/src/Backend/Renderer/OpenGL.cppm @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.cpp b/src/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.cpp index 385784f53..300cf6714 100644 --- a/src/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.cpp +++ b/src/Backend/Renderer/OpenGL3/BackendRenderTargetOpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.cpp b/src/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.cpp index 4aa846cca..a75d8579b 100644 --- a/src/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.cpp +++ b/src/Backend/Renderer/OpenGL3/BackendRendererOpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.cpp b/src/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.cpp index 857f8a977..5a09091b8 100644 --- a/src/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.cpp +++ b/src/Backend/Renderer/OpenGL3/BackendTextureOpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/OpenGL3/CanvasOpenGL3.cpp b/src/Backend/Renderer/OpenGL3/CanvasOpenGL3.cpp index a1b3e434f..0a2b19ac2 100644 --- a/src/Backend/Renderer/OpenGL3/CanvasOpenGL3.cpp +++ b/src/Backend/Renderer/OpenGL3/CanvasOpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/Raylib/BackendRenderTargetRaylib.cpp b/src/Backend/Renderer/Raylib/BackendRenderTargetRaylib.cpp index e866c41cf..f616078e6 100644 --- a/src/Backend/Renderer/Raylib/BackendRenderTargetRaylib.cpp +++ b/src/Backend/Renderer/Raylib/BackendRenderTargetRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/Raylib/BackendRendererRaylib.cpp b/src/Backend/Renderer/Raylib/BackendRendererRaylib.cpp index 8d33ba130..f4ec474fe 100644 --- a/src/Backend/Renderer/Raylib/BackendRendererRaylib.cpp +++ b/src/Backend/Renderer/Raylib/BackendRendererRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/Raylib/BackendTextureRaylib.cpp b/src/Backend/Renderer/Raylib/BackendTextureRaylib.cpp index d9ca66409..e8e71ab4e 100644 --- a/src/Backend/Renderer/Raylib/BackendTextureRaylib.cpp +++ b/src/Backend/Renderer/Raylib/BackendTextureRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/Raylib/CanvasRaylib.cpp b/src/Backend/Renderer/Raylib/CanvasRaylib.cpp index ce2a71c93..64678656b 100644 --- a/src/Backend/Renderer/Raylib/CanvasRaylib.cpp +++ b/src/Backend/Renderer/Raylib/CanvasRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.cpp b/src/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.cpp index 6ad755b99..32594d353 100644 --- a/src/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.cpp +++ b/src/Backend/Renderer/SDL_Renderer/BackendRenderTargetSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SDL_Renderer/BackendRendererSDL.cpp b/src/Backend/Renderer/SDL_Renderer/BackendRendererSDL.cpp index 8e8a2b4f3..87a906dcb 100644 --- a/src/Backend/Renderer/SDL_Renderer/BackendRendererSDL.cpp +++ b/src/Backend/Renderer/SDL_Renderer/BackendRendererSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SDL_Renderer/BackendTextureSDL.cpp b/src/Backend/Renderer/SDL_Renderer/BackendTextureSDL.cpp index 2f84bcecf..f3bbe69ba 100644 --- a/src/Backend/Renderer/SDL_Renderer/BackendTextureSDL.cpp +++ b/src/Backend/Renderer/SDL_Renderer/BackendTextureSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SDL_Renderer/CanvasSDL.cpp b/src/Backend/Renderer/SDL_Renderer/CanvasSDL.cpp index fefdffb4d..495f9c69b 100644 --- a/src/Backend/Renderer/SDL_Renderer/CanvasSDL.cpp +++ b/src/Backend/Renderer/SDL_Renderer/CanvasSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.cpp b/src/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.cpp index 7b3e0a397..e1619f3da 100644 --- a/src/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/BackendRenderTargetSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SFML-Graphics/BackendRendererSFML.cpp b/src/Backend/Renderer/SFML-Graphics/BackendRendererSFML.cpp index c539c08d4..2b6285e23 100644 --- a/src/Backend/Renderer/SFML-Graphics/BackendRendererSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/BackendRendererSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SFML-Graphics/BackendTextureSFML.cpp b/src/Backend/Renderer/SFML-Graphics/BackendTextureSFML.cpp index 2052417e4..97cf48ac9 100644 --- a/src/Backend/Renderer/SFML-Graphics/BackendTextureSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/BackendTextureSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp index a027659ba..94ed57784 100644 --- a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SDL-GLES2.cpp b/src/Backend/SDL-GLES2.cpp index fcde1788c..7a2d25987 100644 --- a/src/Backend/SDL-GLES2.cpp +++ b/src/Backend/SDL-GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SDL-OpenGL3.cpp b/src/Backend/SDL-OpenGL3.cpp index da92d7bc0..c00fe41ef 100644 --- a/src/Backend/SDL-OpenGL3.cpp +++ b/src/Backend/SDL-OpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SDL-Renderer.cpp b/src/Backend/SDL-Renderer.cpp index ac5dd47ec..b832de1a9 100644 --- a/src/Backend/SDL-Renderer.cpp +++ b/src/Backend/SDL-Renderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SDL-TTF-GLES2.cpp b/src/Backend/SDL-TTF-GLES2.cpp index 14ae38c72..2abe7423e 100644 --- a/src/Backend/SDL-TTF-GLES2.cpp +++ b/src/Backend/SDL-TTF-GLES2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SDL-TTF-OpenGL3.cpp b/src/Backend/SDL-TTF-OpenGL3.cpp index e8e212d85..5e4e6785e 100644 --- a/src/Backend/SDL-TTF-OpenGL3.cpp +++ b/src/Backend/SDL-TTF-OpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SFML-Graphics.cpp b/src/Backend/SFML-Graphics.cpp index 99af7c81d..f1a79c87f 100644 --- a/src/Backend/SFML-Graphics.cpp +++ b/src/Backend/SFML-Graphics.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/SFML-OpenGL3.cpp b/src/Backend/SFML-OpenGL3.cpp index a5fc3d06c..e137b71b3 100644 --- a/src/Backend/SFML-OpenGL3.cpp +++ b/src/Backend/SFML-OpenGL3.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/Backend.cpp b/src/Backend/Window/Backend.cpp index 2a58cbcc4..368847d83 100644 --- a/src/Backend/Window/Backend.cpp +++ b/src/Backend/Window/Backend.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/BackendGui.cpp b/src/Backend/Window/BackendGui.cpp index 83201646d..e26f15df5 100644 --- a/src/Backend/Window/BackendGui.cpp +++ b/src/Backend/Window/BackendGui.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/GLFW/BackendGLFW.cpp b/src/Backend/Window/GLFW/BackendGLFW.cpp index 8d4256fc7..dae7deb31 100644 --- a/src/Backend/Window/GLFW/BackendGLFW.cpp +++ b/src/Backend/Window/GLFW/BackendGLFW.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/GLFW/BackendGuiGLFW.cpp b/src/Backend/Window/GLFW/BackendGuiGLFW.cpp index 74a7c89e6..d66ae3476 100644 --- a/src/Backend/Window/GLFW/BackendGuiGLFW.cpp +++ b/src/Backend/Window/GLFW/BackendGuiGLFW.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/Raylib/BackendGuiRaylib.cpp b/src/Backend/Window/Raylib/BackendGuiRaylib.cpp index 858157ef0..ef7340af9 100644 --- a/src/Backend/Window/Raylib/BackendGuiRaylib.cpp +++ b/src/Backend/Window/Raylib/BackendGuiRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/Raylib/BackendRaylib.cpp b/src/Backend/Window/Raylib/BackendRaylib.cpp index 5fcd1372d..8dd69a217 100644 --- a/src/Backend/Window/Raylib/BackendRaylib.cpp +++ b/src/Backend/Window/Raylib/BackendRaylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/SDL/BackendGuiSDL.cpp b/src/Backend/Window/SDL/BackendGuiSDL.cpp index 77351cc14..7e6190ddf 100644 --- a/src/Backend/Window/SDL/BackendGuiSDL.cpp +++ b/src/Backend/Window/SDL/BackendGuiSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/SDL/BackendSDL.cpp b/src/Backend/Window/SDL/BackendSDL.cpp index d320d640b..dd410c8ed 100644 --- a/src/Backend/Window/SDL/BackendSDL.cpp +++ b/src/Backend/Window/SDL/BackendSDL.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/SFML/BackendGuiSFML.cpp b/src/Backend/Window/SFML/BackendGuiSFML.cpp index 8e29889cf..19962993c 100644 --- a/src/Backend/Window/SFML/BackendGuiSFML.cpp +++ b/src/Backend/Window/SFML/BackendGuiSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/Window/SFML/BackendSFML.cpp b/src/Backend/Window/SFML/BackendSFML.cpp index e7a4a6e35..cc8699fa6 100644 --- a/src/Backend/Window/SFML/BackendSFML.cpp +++ b/src/Backend/Window/SFML/BackendSFML.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Backend/raylib.cpp b/src/Backend/raylib.cpp index 6376a2669..5451bc2af 100644 --- a/src/Backend/raylib.cpp +++ b/src/Backend/raylib.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Base64.cpp b/src/Base64.cpp index 9283b3a6e..41ee9aaaf 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c14d1c34..8b7defd02 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Color.cpp b/src/Color.cpp index 9efc30d8d..68112b4e4 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Components.cpp b/src/Components.cpp index 2505ca538..277af8f50 100644 --- a/src/Components.cpp +++ b/src/Components.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Container.cpp b/src/Container.cpp index 5ca63e91f..9adebb018 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Cursor.cpp b/src/Cursor.cpp index d9fc9a889..ba7344b8a 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/CustomWidgetForBindings.cpp b/src/CustomWidgetForBindings.cpp index db094951c..99e0c489b 100644 --- a/src/CustomWidgetForBindings.cpp +++ b/src/CustomWidgetForBindings.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/DefaultBackendWindow.cpp b/src/DefaultBackendWindow.cpp index cd6c697ff..92fef82ce 100644 --- a/src/DefaultBackendWindow.cpp +++ b/src/DefaultBackendWindow.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/FileDialogIconLoader.cpp b/src/FileDialogIconLoader.cpp index 23932df59..64c7907f5 100644 --- a/src/FileDialogIconLoader.cpp +++ b/src/FileDialogIconLoader.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/FileDialogIconLoaderLinux.cpp b/src/FileDialogIconLoaderLinux.cpp index df9865ce3..160044d24 100644 --- a/src/FileDialogIconLoaderLinux.cpp +++ b/src/FileDialogIconLoaderLinux.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/FileDialogIconLoaderWindows.cpp b/src/FileDialogIconLoaderWindows.cpp index c11c8dbec..0bb6f42e1 100644 --- a/src/FileDialogIconLoaderWindows.cpp +++ b/src/FileDialogIconLoaderWindows.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Filesystem.cpp b/src/Filesystem.cpp index db27b1a48..79b40ccc5 100755 --- a/src/Filesystem.cpp +++ b/src/Filesystem.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Font.cpp b/src/Font.cpp index 1672469ef..725fc8eae 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Global.cpp b/src/Global.cpp index aec608a51..277cc35a8 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Layout.cpp b/src/Layout.cpp index d58d9b368..6f3bff4e5 100644 --- a/src/Layout.cpp +++ b/src/Layout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/DataIO.cpp b/src/Loading/DataIO.cpp index d1d179cdd..9a7237a55 100644 --- a/src/Loading/DataIO.cpp +++ b/src/Loading/DataIO.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/Deserializer.cpp b/src/Loading/Deserializer.cpp index 6eb557de5..7cdb7d0c1 100644 --- a/src/Loading/Deserializer.cpp +++ b/src/Loading/Deserializer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/ImageLoader.cpp b/src/Loading/ImageLoader.cpp index 5e273c895..c776740e7 100644 --- a/src/Loading/ImageLoader.cpp +++ b/src/Loading/ImageLoader.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/Serializer.cpp b/src/Loading/Serializer.cpp index 81a620968..e7fd4cddf 100644 --- a/src/Loading/Serializer.cpp +++ b/src/Loading/Serializer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/Theme.cpp b/src/Loading/Theme.cpp index b7f6b692d..77c5edead 100644 --- a/src/Loading/Theme.cpp +++ b/src/Loading/Theme.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/ThemeLoader.cpp b/src/Loading/ThemeLoader.cpp index 262045ec9..26c412f11 100644 --- a/src/Loading/ThemeLoader.cpp +++ b/src/Loading/ThemeLoader.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Loading/WidgetFactory.cpp b/src/Loading/WidgetFactory.cpp index 1afad767d..a0bb3afd1 100644 --- a/src/Loading/WidgetFactory.cpp +++ b/src/Loading/WidgetFactory.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/ObjectConverter.cpp b/src/ObjectConverter.cpp index 1712ee131..9020d649b 100644 --- a/src/ObjectConverter.cpp +++ b/src/ObjectConverter.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/BoxLayoutRenderer.cpp b/src/Renderers/BoxLayoutRenderer.cpp index cebb86477..332121865 100644 --- a/src/Renderers/BoxLayoutRenderer.cpp +++ b/src/Renderers/BoxLayoutRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ButtonRenderer.cpp b/src/Renderers/ButtonRenderer.cpp index a8f04d7c7..65e5a0736 100644 --- a/src/Renderers/ButtonRenderer.cpp +++ b/src/Renderers/ButtonRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ChatBoxRenderer.cpp b/src/Renderers/ChatBoxRenderer.cpp index fc886ff54..8e9784e0f 100644 --- a/src/Renderers/ChatBoxRenderer.cpp +++ b/src/Renderers/ChatBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ChildWindowRenderer.cpp b/src/Renderers/ChildWindowRenderer.cpp index e275a7013..befdd5b44 100644 --- a/src/Renderers/ChildWindowRenderer.cpp +++ b/src/Renderers/ChildWindowRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ColorPickerRenderer.cpp b/src/Renderers/ColorPickerRenderer.cpp index 38476a68e..5a863b3db 100644 --- a/src/Renderers/ColorPickerRenderer.cpp +++ b/src/Renderers/ColorPickerRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ComboBoxRenderer.cpp b/src/Renderers/ComboBoxRenderer.cpp index b3ea59f57..a433e9499 100644 --- a/src/Renderers/ComboBoxRenderer.cpp +++ b/src/Renderers/ComboBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/EditBoxRenderer.cpp b/src/Renderers/EditBoxRenderer.cpp index ec1591e53..19ba244db 100644 --- a/src/Renderers/EditBoxRenderer.cpp +++ b/src/Renderers/EditBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/FileDialogRenderer.cpp b/src/Renderers/FileDialogRenderer.cpp index 7ab3b1ea2..59fd8d115 100644 --- a/src/Renderers/FileDialogRenderer.cpp +++ b/src/Renderers/FileDialogRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/GroupRenderer.cpp b/src/Renderers/GroupRenderer.cpp index 52827573e..d0447f045 100644 --- a/src/Renderers/GroupRenderer.cpp +++ b/src/Renderers/GroupRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/KnobRenderer.cpp b/src/Renderers/KnobRenderer.cpp index 5576d83d3..78aa2d941 100644 --- a/src/Renderers/KnobRenderer.cpp +++ b/src/Renderers/KnobRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/LabelRenderer.cpp b/src/Renderers/LabelRenderer.cpp index f105ad8a1..05fd0fc7d 100644 --- a/src/Renderers/LabelRenderer.cpp +++ b/src/Renderers/LabelRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ListBoxRenderer.cpp b/src/Renderers/ListBoxRenderer.cpp index ad0e53c34..ec6d62a47 100644 --- a/src/Renderers/ListBoxRenderer.cpp +++ b/src/Renderers/ListBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ListViewRenderer.cpp b/src/Renderers/ListViewRenderer.cpp index bc66f9c0d..358665af8 100644 --- a/src/Renderers/ListViewRenderer.cpp +++ b/src/Renderers/ListViewRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/MessageBoxRenderer.cpp b/src/Renderers/MessageBoxRenderer.cpp index bef131b17..34e8427cf 100644 --- a/src/Renderers/MessageBoxRenderer.cpp +++ b/src/Renderers/MessageBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/PanelListBoxRenderer.cpp b/src/Renderers/PanelListBoxRenderer.cpp index d2287707c..15ffc94c8 100644 --- a/src/Renderers/PanelListBoxRenderer.cpp +++ b/src/Renderers/PanelListBoxRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/PanelRenderer.cpp b/src/Renderers/PanelRenderer.cpp index 990d86a8d..d2e33ab77 100644 --- a/src/Renderers/PanelRenderer.cpp +++ b/src/Renderers/PanelRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/PictureRenderer.cpp b/src/Renderers/PictureRenderer.cpp index f878b4abd..04bbd6fb2 100644 --- a/src/Renderers/PictureRenderer.cpp +++ b/src/Renderers/PictureRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ProgressBarRenderer.cpp b/src/Renderers/ProgressBarRenderer.cpp index 769c455e3..4f8da2273 100644 --- a/src/Renderers/ProgressBarRenderer.cpp +++ b/src/Renderers/ProgressBarRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/RadioButtonRenderer.cpp b/src/Renderers/RadioButtonRenderer.cpp index 9c98f29a3..5db50633c 100644 --- a/src/Renderers/RadioButtonRenderer.cpp +++ b/src/Renderers/RadioButtonRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/RangeSliderRenderer.cpp b/src/Renderers/RangeSliderRenderer.cpp index fa276b536..a6b8c98c0 100644 --- a/src/Renderers/RangeSliderRenderer.cpp +++ b/src/Renderers/RangeSliderRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ScrollablePanelRenderer.cpp b/src/Renderers/ScrollablePanelRenderer.cpp index 676f5d6d5..50ef09642 100644 --- a/src/Renderers/ScrollablePanelRenderer.cpp +++ b/src/Renderers/ScrollablePanelRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/ScrollbarRenderer.cpp b/src/Renderers/ScrollbarRenderer.cpp index df798e308..599a5a575 100644 --- a/src/Renderers/ScrollbarRenderer.cpp +++ b/src/Renderers/ScrollbarRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/SeparatorLineRenderer.cpp b/src/Renderers/SeparatorLineRenderer.cpp index 044fb6613..d90e2d6bd 100644 --- a/src/Renderers/SeparatorLineRenderer.cpp +++ b/src/Renderers/SeparatorLineRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/SliderRenderer.cpp b/src/Renderers/SliderRenderer.cpp index 8641cdcd3..da327586f 100644 --- a/src/Renderers/SliderRenderer.cpp +++ b/src/Renderers/SliderRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/SpinButtonRenderer.cpp b/src/Renderers/SpinButtonRenderer.cpp index 78826f74e..e7d74e446 100644 --- a/src/Renderers/SpinButtonRenderer.cpp +++ b/src/Renderers/SpinButtonRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/SplitContainerRenderer.cpp b/src/Renderers/SplitContainerRenderer.cpp index 65fea0bed..ef99ffc2f 100644 --- a/src/Renderers/SplitContainerRenderer.cpp +++ b/src/Renderers/SplitContainerRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/TabsRenderer.cpp b/src/Renderers/TabsRenderer.cpp index 4326ade52..6fe66c992 100644 --- a/src/Renderers/TabsRenderer.cpp +++ b/src/Renderers/TabsRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/TextAreaRenderer.cpp b/src/Renderers/TextAreaRenderer.cpp index 624690e66..43020694a 100644 --- a/src/Renderers/TextAreaRenderer.cpp +++ b/src/Renderers/TextAreaRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/TreeViewRenderer.cpp b/src/Renderers/TreeViewRenderer.cpp index eac11e6f8..fabe92a2e 100644 --- a/src/Renderers/TreeViewRenderer.cpp +++ b/src/Renderers/TreeViewRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Renderers/WidgetRenderer.cpp b/src/Renderers/WidgetRenderer.cpp index 7c71d7cad..60dbc18e1 100644 --- a/src/Renderers/WidgetRenderer.cpp +++ b/src/Renderers/WidgetRenderer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Signal.cpp b/src/Signal.cpp index 6ce9ab663..abf9cb77e 100644 --- a/src/Signal.cpp +++ b/src/Signal.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/SignalManager.cpp b/src/SignalManager.cpp index 869b01802..a24b315cd 100644 --- a/src/SignalManager.cpp +++ b/src/SignalManager.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Sprite.cpp b/src/Sprite.cpp index 6eb976707..317679ef9 100644 --- a/src/Sprite.cpp +++ b/src/Sprite.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/String.cpp b/src/String.cpp index 67045878b..6bd99108e 100644 --- a/src/String.cpp +++ b/src/String.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/SubwidgetContainer.cpp b/src/SubwidgetContainer.cpp index 972917008..a06f2f8aa 100644 --- a/src/SubwidgetContainer.cpp +++ b/src/SubwidgetContainer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/SvgImage.cpp b/src/SvgImage.cpp index 6b70472d9..e1f5ce0bc 100644 --- a/src/SvgImage.cpp +++ b/src/SvgImage.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/TGUI-Main-Module.cppm.in b/src/TGUI-Main-Module.cppm.in index 643d20e7b..fcc70c9e3 100644 --- a/src/TGUI-Main-Module.cppm.in +++ b/src/TGUI-Main-Module.cppm.in @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/TGUI-Module.cppm.in b/src/TGUI-Module.cppm.in index 30eeb9796..74b04ebbd 100644 --- a/src/TGUI-Module.cppm.in +++ b/src/TGUI-Module.cppm.in @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Text.cpp b/src/Text.cpp index 048b27278..cafb5d6a0 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/TextStyle.cpp b/src/TextStyle.cpp index ad715b749..ead59b521 100644 --- a/src/TextStyle.cpp +++ b/src/TextStyle.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Texture.cpp b/src/Texture.cpp index dc24827f2..6a0eb5e7e 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/TextureManager.cpp b/src/TextureManager.cpp index ebf1a294d..36f4b26bf 100644 --- a/src/TextureManager.cpp +++ b/src/TextureManager.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Timer.cpp b/src/Timer.cpp index 5d01aede3..013fae216 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/ToolTip.cpp b/src/ToolTip.cpp index cb2b7410e..11db8fcc3 100644 --- a/src/ToolTip.cpp +++ b/src/ToolTip.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Transform.cpp b/src/Transform.cpp index a77b6c6ba..2fae98a80 100644 --- a/src/Transform.cpp +++ b/src/Transform.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/TwoFingerScrollDetect.cpp b/src/TwoFingerScrollDetect.cpp index feb4f2898..2f5c61d5d 100644 --- a/src/TwoFingerScrollDetect.cpp +++ b/src/TwoFingerScrollDetect.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widget.cpp b/src/Widget.cpp index 0bb87a000..b7f0ac413 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/BitmapButton.cpp b/src/Widgets/BitmapButton.cpp index 45f349f37..958761681 100644 --- a/src/Widgets/BitmapButton.cpp +++ b/src/Widgets/BitmapButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/BoxLayout.cpp b/src/Widgets/BoxLayout.cpp index 5f0543633..fa93ad066 100644 --- a/src/Widgets/BoxLayout.cpp +++ b/src/Widgets/BoxLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/BoxLayoutRatios.cpp b/src/Widgets/BoxLayoutRatios.cpp index 4c8a3804b..49bced51d 100644 --- a/src/Widgets/BoxLayoutRatios.cpp +++ b/src/Widgets/BoxLayoutRatios.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Button.cpp b/src/Widgets/Button.cpp index 7db23f533..ed877a790 100644 --- a/src/Widgets/Button.cpp +++ b/src/Widgets/Button.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ButtonBase.cpp b/src/Widgets/ButtonBase.cpp index 89d9893e1..0043086e1 100644 --- a/src/Widgets/ButtonBase.cpp +++ b/src/Widgets/ButtonBase.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/CanvasBase.cpp b/src/Widgets/CanvasBase.cpp index 7a0e9ee2c..a57f70141 100644 --- a/src/Widgets/CanvasBase.cpp +++ b/src/Widgets/CanvasBase.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ChatBox.cpp b/src/Widgets/ChatBox.cpp index 3f1326214..03bffa662 100644 --- a/src/Widgets/ChatBox.cpp +++ b/src/Widgets/ChatBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/CheckBox.cpp b/src/Widgets/CheckBox.cpp index 04e970b1c..4660da697 100644 --- a/src/Widgets/CheckBox.cpp +++ b/src/Widgets/CheckBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ChildWindow.cpp b/src/Widgets/ChildWindow.cpp index e0f36c1aa..c0cc41745 100644 --- a/src/Widgets/ChildWindow.cpp +++ b/src/Widgets/ChildWindow.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ClickableWidget.cpp b/src/Widgets/ClickableWidget.cpp index c05d28d9d..88ad78a89 100644 --- a/src/Widgets/ClickableWidget.cpp +++ b/src/Widgets/ClickableWidget.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ColorPicker.cpp b/src/Widgets/ColorPicker.cpp index d5e239ad5..14b8bb269 100644 --- a/src/Widgets/ColorPicker.cpp +++ b/src/Widgets/ColorPicker.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ComboBox.cpp b/src/Widgets/ComboBox.cpp index ac41039fa..c38af087b 100644 --- a/src/Widgets/ComboBox.cpp +++ b/src/Widgets/ComboBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/EditBox.cpp b/src/Widgets/EditBox.cpp index 4b27c0d76..6ad737b73 100644 --- a/src/Widgets/EditBox.cpp +++ b/src/Widgets/EditBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/FileDialog.cpp b/src/Widgets/FileDialog.cpp index 07aa03161..a41b08f29 100755 --- a/src/Widgets/FileDialog.cpp +++ b/src/Widgets/FileDialog.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Grid.cpp b/src/Widgets/Grid.cpp index bacbc139f..8d470e3d1 100644 --- a/src/Widgets/Grid.cpp +++ b/src/Widgets/Grid.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Group.cpp b/src/Widgets/Group.cpp index 4c4c19090..2feaa64b3 100644 --- a/src/Widgets/Group.cpp +++ b/src/Widgets/Group.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/GrowHorizontalLayout.cpp b/src/Widgets/GrowHorizontalLayout.cpp index 00e0c31d0..a1e594710 100644 --- a/src/Widgets/GrowHorizontalLayout.cpp +++ b/src/Widgets/GrowHorizontalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/GrowVerticalLayout.cpp b/src/Widgets/GrowVerticalLayout.cpp index 20731ed49..942b46399 100644 --- a/src/Widgets/GrowVerticalLayout.cpp +++ b/src/Widgets/GrowVerticalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/HorizontalLayout.cpp b/src/Widgets/HorizontalLayout.cpp index 3b46beec4..76711182a 100644 --- a/src/Widgets/HorizontalLayout.cpp +++ b/src/Widgets/HorizontalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/HorizontalWrap.cpp b/src/Widgets/HorizontalWrap.cpp index 1a57545ea..f5aaf64b2 100644 --- a/src/Widgets/HorizontalWrap.cpp +++ b/src/Widgets/HorizontalWrap.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Knob.cpp b/src/Widgets/Knob.cpp index 346c86798..f07fa759d 100644 --- a/src/Widgets/Knob.cpp +++ b/src/Widgets/Knob.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Label.cpp b/src/Widgets/Label.cpp index 1cf6c24e5..abf71e7ec 100644 --- a/src/Widgets/Label.cpp +++ b/src/Widgets/Label.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ListBox.cpp b/src/Widgets/ListBox.cpp index 5d7d36eb9..63b519647 100644 --- a/src/Widgets/ListBox.cpp +++ b/src/Widgets/ListBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ListView.cpp b/src/Widgets/ListView.cpp index 825134add..5e8710392 100644 --- a/src/Widgets/ListView.cpp +++ b/src/Widgets/ListView.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/MessageBox.cpp b/src/Widgets/MessageBox.cpp index 77e82ab06..007e97135 100644 --- a/src/Widgets/MessageBox.cpp +++ b/src/Widgets/MessageBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Panel.cpp b/src/Widgets/Panel.cpp index 5df02aba9..4dbb254b2 100644 --- a/src/Widgets/Panel.cpp +++ b/src/Widgets/Panel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/PanelListBox.cpp b/src/Widgets/PanelListBox.cpp index 994f814d1..b916e906b 100644 --- a/src/Widgets/PanelListBox.cpp +++ b/src/Widgets/PanelListBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Picture.cpp b/src/Widgets/Picture.cpp index 6d14adf37..7d3c20e98 100644 --- a/src/Widgets/Picture.cpp +++ b/src/Widgets/Picture.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ProgressBar.cpp b/src/Widgets/ProgressBar.cpp index d0515e4d3..bea437800 100644 --- a/src/Widgets/ProgressBar.cpp +++ b/src/Widgets/ProgressBar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/RadioButton.cpp b/src/Widgets/RadioButton.cpp index 31e45e2c8..562239696 100644 --- a/src/Widgets/RadioButton.cpp +++ b/src/Widgets/RadioButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/RadioButtonGroup.cpp b/src/Widgets/RadioButtonGroup.cpp index 56e2951b3..bafd95690 100644 --- a/src/Widgets/RadioButtonGroup.cpp +++ b/src/Widgets/RadioButtonGroup.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/RangeSlider.cpp b/src/Widgets/RangeSlider.cpp index 1431628ce..1a4bdb8c1 100644 --- a/src/Widgets/RangeSlider.cpp +++ b/src/Widgets/RangeSlider.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/RichTextLabel.cpp b/src/Widgets/RichTextLabel.cpp index f33e1ada8..4051d02cc 100644 --- a/src/Widgets/RichTextLabel.cpp +++ b/src/Widgets/RichTextLabel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ScrollablePanel.cpp b/src/Widgets/ScrollablePanel.cpp index e0105db5a..fa745dbc6 100644 --- a/src/Widgets/ScrollablePanel.cpp +++ b/src/Widgets/ScrollablePanel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Scrollbar.cpp b/src/Widgets/Scrollbar.cpp index 08c6a89c1..4ffa59629 100644 --- a/src/Widgets/Scrollbar.cpp +++ b/src/Widgets/Scrollbar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/SeparatorLine.cpp b/src/Widgets/SeparatorLine.cpp index 1fa90d262..d9cb2c196 100644 --- a/src/Widgets/SeparatorLine.cpp +++ b/src/Widgets/SeparatorLine.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Slider.cpp b/src/Widgets/Slider.cpp index 62a7a8105..7ead08b3c 100644 --- a/src/Widgets/Slider.cpp +++ b/src/Widgets/Slider.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/SpinButton.cpp b/src/Widgets/SpinButton.cpp index 907838549..05086bd5b 100644 --- a/src/Widgets/SpinButton.cpp +++ b/src/Widgets/SpinButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/SpinControl.cpp b/src/Widgets/SpinControl.cpp index 1efe18660..4ed3d820f 100644 --- a/src/Widgets/SpinControl.cpp +++ b/src/Widgets/SpinControl.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/SplitContainer.cpp b/src/Widgets/SplitContainer.cpp index 1909a3209..f4b068d5f 100644 --- a/src/Widgets/SplitContainer.cpp +++ b/src/Widgets/SplitContainer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/TabContainer.cpp b/src/Widgets/TabContainer.cpp index d0416d616..f2cef354d 100644 --- a/src/Widgets/TabContainer.cpp +++ b/src/Widgets/TabContainer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/Tabs.cpp b/src/Widgets/Tabs.cpp index ebec1b5a6..69d0fd6eb 100644 --- a/src/Widgets/Tabs.cpp +++ b/src/Widgets/Tabs.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/TextArea.cpp b/src/Widgets/TextArea.cpp index db31c31a4..0e3df7bdb 100644 --- a/src/Widgets/TextArea.cpp +++ b/src/Widgets/TextArea.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/ToggleButton.cpp b/src/Widgets/ToggleButton.cpp index 1a58e421c..9fb32d830 100644 --- a/src/Widgets/ToggleButton.cpp +++ b/src/Widgets/ToggleButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/TreeView.cpp b/src/Widgets/TreeView.cpp index bdb9298f7..948b66a01 100644 --- a/src/Widgets/TreeView.cpp +++ b/src/Widgets/TreeView.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/Widgets/VerticalLayout.cpp b/src/Widgets/VerticalLayout.cpp index d2800933d..764dc9880 100644 --- a/src/Widgets/VerticalLayout.cpp +++ b/src/Widgets/VerticalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/src/WindowsIMM.cpp b/src/WindowsIMM.cpp index 32c108a7b..588a52bac 100644 --- a/src/WindowsIMM.cpp +++ b/src/WindowsIMM.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/AbsoluteOrRelativeValue.cpp b/tests/AbsoluteOrRelativeValue.cpp index 20b753ca9..adaa6c176 100644 --- a/tests/AbsoluteOrRelativeValue.cpp +++ b/tests/AbsoluteOrRelativeValue.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Animation.cpp b/tests/Animation.cpp index a25f7e85f..4fa7d8eca 100644 --- a/tests/Animation.cpp +++ b/tests/Animation.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/BackendEvents.cpp b/tests/BackendEvents.cpp index 5c2e9795a..af04ef057 100644 --- a/tests/BackendEvents.cpp +++ b/tests/BackendEvents.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6e15054ab..194d73e07 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,6 @@ #################################################################################################### # TGUI - Texus' Graphical User Interface -# Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +# Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) # # This software is provided 'as-is', without any express or implied warranty. # In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Clipboard.cpp b/tests/Clipboard.cpp index ab22dc82b..90aa5f30b 100644 --- a/tests/Clipboard.cpp +++ b/tests/Clipboard.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Clipping.cpp b/tests/Clipping.cpp index 0717ea952..793aeae41 100644 --- a/tests/Clipping.cpp +++ b/tests/Clipping.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Color.cpp b/tests/Color.cpp index 9ba6a53ad..b408b358c 100644 --- a/tests/Color.cpp +++ b/tests/Color.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/CompareFiles.cpp b/tests/CompareFiles.cpp index 787192f2c..53c358289 100644 --- a/tests/CompareFiles.cpp +++ b/tests/CompareFiles.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Container.cpp b/tests/Container.cpp index 70d567d49..9bb55f6eb 100644 --- a/tests/Container.cpp +++ b/tests/Container.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Duration.cpp b/tests/Duration.cpp index d82a667ec..2f834b3fa 100644 --- a/tests/Duration.cpp +++ b/tests/Duration.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Filesystem.cpp b/tests/Filesystem.cpp index c693c904e..94bee3741 100644 --- a/tests/Filesystem.cpp +++ b/tests/Filesystem.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Focus.cpp b/tests/Focus.cpp index 8bcce2e52..ae06697ad 100644 --- a/tests/Focus.cpp +++ b/tests/Focus.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Font.cpp b/tests/Font.cpp index b839707de..a6f590b89 100644 --- a/tests/Font.cpp +++ b/tests/Font.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Layouts.cpp b/tests/Layouts.cpp index a93ed70c3..37ebbb2fc 100644 --- a/tests/Layouts.cpp +++ b/tests/Layouts.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Loading/DataIO.cpp b/tests/Loading/DataIO.cpp index b20b4a03a..d37964fbd 100644 --- a/tests/Loading/DataIO.cpp +++ b/tests/Loading/DataIO.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Loading/Deserializer.cpp b/tests/Loading/Deserializer.cpp index 64214c29c..2916c2a5b 100644 --- a/tests/Loading/Deserializer.cpp +++ b/tests/Loading/Deserializer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Loading/Serializer.cpp b/tests/Loading/Serializer.cpp index fc968db60..f5ab2d8af 100644 --- a/tests/Loading/Serializer.cpp +++ b/tests/Loading/Serializer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Loading/Theme.cpp b/tests/Loading/Theme.cpp index cea0cd508..1cf0a762e 100644 --- a/tests/Loading/Theme.cpp +++ b/tests/Loading/Theme.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Loading/ThemeLoader.cpp b/tests/Loading/ThemeLoader.cpp index cd2b10f2c..5fed73439 100644 --- a/tests/Loading/ThemeLoader.cpp +++ b/tests/Loading/ThemeLoader.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/MouseCursors.cpp b/tests/MouseCursors.cpp index 85f5ec9a2..cd077836f 100644 --- a/tests/MouseCursors.cpp +++ b/tests/MouseCursors.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Outline.cpp b/tests/Outline.cpp index abe637c18..3ec9f3e72 100644 --- a/tests/Outline.cpp +++ b/tests/Outline.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Signal.cpp b/tests/Signal.cpp index 817ab5b2e..2ffec0387 100644 --- a/tests/Signal.cpp +++ b/tests/Signal.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/SignalManager.cpp b/tests/SignalManager.cpp index 9a220427c..9d0265027 100644 --- a/tests/SignalManager.cpp +++ b/tests/SignalManager.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Sprite.cpp b/tests/Sprite.cpp index 6ddedd7ba..9609105c8 100644 --- a/tests/Sprite.cpp +++ b/tests/Sprite.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/String.cpp b/tests/String.cpp index 40ffbfcf7..d34ea73cf 100644 --- a/tests/String.cpp +++ b/tests/String.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/SvgImage.cpp b/tests/SvgImage.cpp index d95c1d32a..abd9daaa2 100644 --- a/tests/SvgImage.cpp +++ b/tests/SvgImage.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Tests.cpp b/tests/Tests.cpp index 80464264f..9eccd3762 100644 --- a/tests/Tests.cpp +++ b/tests/Tests.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Tests.hpp b/tests/Tests.hpp index 941cd189a..971e3fd5a 100644 --- a/tests/Tests.hpp +++ b/tests/Tests.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Text.cpp b/tests/Text.cpp index a783621e4..07735c4bf 100644 --- a/tests/Text.cpp +++ b/tests/Text.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Texture.cpp b/tests/Texture.cpp index 107bdc735..43ae3eb91 100644 --- a/tests/Texture.cpp +++ b/tests/Texture.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/TextureManager.cpp b/tests/TextureManager.cpp index 4ac1231f5..2e8ffc829 100644 --- a/tests/TextureManager.cpp +++ b/tests/TextureManager.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Timer.cpp b/tests/Timer.cpp index 049453332..57db32a43 100644 --- a/tests/Timer.cpp +++ b/tests/Timer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/ToolTip.cpp b/tests/ToolTip.cpp index 4b0daf509..d4ab7d3a2 100644 --- a/tests/ToolTip.cpp +++ b/tests/ToolTip.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Vector2.cpp b/tests/Vector2.cpp index 8b82e6464..e6977a612 100644 --- a/tests/Vector2.cpp +++ b/tests/Vector2.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widget.cpp b/tests/Widget.cpp index a813db207..82ee97de7 100644 --- a/tests/Widget.cpp +++ b/tests/Widget.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/BitmapButton.cpp b/tests/Widgets/BitmapButton.cpp index d69e4b41d..cfe253b4f 100644 --- a/tests/Widgets/BitmapButton.cpp +++ b/tests/Widgets/BitmapButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Button.cpp b/tests/Widgets/Button.cpp index f34c94ebc..4b257b894 100644 --- a/tests/Widgets/Button.cpp +++ b/tests/Widgets/Button.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Canvas.cpp b/tests/Widgets/Canvas.cpp index fada6c78d..eae7efff7 100644 --- a/tests/Widgets/Canvas.cpp +++ b/tests/Widgets/Canvas.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ChatBox.cpp b/tests/Widgets/ChatBox.cpp index a64bae598..2c39e6d0d 100644 --- a/tests/Widgets/ChatBox.cpp +++ b/tests/Widgets/ChatBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/CheckBox.cpp b/tests/Widgets/CheckBox.cpp index 95785d1fa..15fdbb253 100644 --- a/tests/Widgets/CheckBox.cpp +++ b/tests/Widgets/CheckBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ChildWindow.cpp b/tests/Widgets/ChildWindow.cpp index 7168ee3bf..08ac50851 100644 --- a/tests/Widgets/ChildWindow.cpp +++ b/tests/Widgets/ChildWindow.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ClickableWidget.cpp b/tests/Widgets/ClickableWidget.cpp index 8fbace0bb..70397351f 100644 --- a/tests/Widgets/ClickableWidget.cpp +++ b/tests/Widgets/ClickableWidget.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ColorPicker.cpp b/tests/Widgets/ColorPicker.cpp index 4b6d765d9..c4fa325f9 100644 --- a/tests/Widgets/ColorPicker.cpp +++ b/tests/Widgets/ColorPicker.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ComboBox.cpp b/tests/Widgets/ComboBox.cpp index 252a7e15a..000b1a0ce 100644 --- a/tests/Widgets/ComboBox.cpp +++ b/tests/Widgets/ComboBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/EditBox.cpp b/tests/Widgets/EditBox.cpp index 1230de7b7..012a8887d 100644 --- a/tests/Widgets/EditBox.cpp +++ b/tests/Widgets/EditBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/EditBoxSlider.cpp b/tests/Widgets/EditBoxSlider.cpp index 48fa0105d..25c4b1ab8 100644 --- a/tests/Widgets/EditBoxSlider.cpp +++ b/tests/Widgets/EditBoxSlider.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/FileDialog.cpp b/tests/Widgets/FileDialog.cpp index 98ca91ed6..577b6621e 100644 --- a/tests/Widgets/FileDialog.cpp +++ b/tests/Widgets/FileDialog.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Grid.cpp b/tests/Widgets/Grid.cpp index 58095f612..f987093d7 100644 --- a/tests/Widgets/Grid.cpp +++ b/tests/Widgets/Grid.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Group.cpp b/tests/Widgets/Group.cpp index 1883155fd..53619dd6f 100644 --- a/tests/Widgets/Group.cpp +++ b/tests/Widgets/Group.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/GrowHorizontalLayout.cpp b/tests/Widgets/GrowHorizontalLayout.cpp index 31b042590..749aac50a 100644 --- a/tests/Widgets/GrowHorizontalLayout.cpp +++ b/tests/Widgets/GrowHorizontalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/GrowVerticalLayout.cpp b/tests/Widgets/GrowVerticalLayout.cpp index 5cf16acab..1af9c1d42 100644 --- a/tests/Widgets/GrowVerticalLayout.cpp +++ b/tests/Widgets/GrowVerticalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/HorizontalLayout.cpp b/tests/Widgets/HorizontalLayout.cpp index 4305c8b71..9a54dbca2 100644 --- a/tests/Widgets/HorizontalLayout.cpp +++ b/tests/Widgets/HorizontalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/HorizontalWrap.cpp b/tests/Widgets/HorizontalWrap.cpp index 4f7840ace..21f6044d1 100644 --- a/tests/Widgets/HorizontalWrap.cpp +++ b/tests/Widgets/HorizontalWrap.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Knob.cpp b/tests/Widgets/Knob.cpp index c0981f025..6d707d553 100644 --- a/tests/Widgets/Knob.cpp +++ b/tests/Widgets/Knob.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Label.cpp b/tests/Widgets/Label.cpp index 257dcdc90..54ab8c664 100644 --- a/tests/Widgets/Label.cpp +++ b/tests/Widgets/Label.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ListBox.cpp b/tests/Widgets/ListBox.cpp index b4d99f30f..8419bd85c 100644 --- a/tests/Widgets/ListBox.cpp +++ b/tests/Widgets/ListBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ListView.cpp b/tests/Widgets/ListView.cpp index e08794159..e708e501d 100644 --- a/tests/Widgets/ListView.cpp +++ b/tests/Widgets/ListView.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/MenuBar.cpp b/tests/Widgets/MenuBar.cpp index 68cbe0691..5cf9375be 100644 --- a/tests/Widgets/MenuBar.cpp +++ b/tests/Widgets/MenuBar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/MessageBox.cpp b/tests/Widgets/MessageBox.cpp index 45b132c51..dfcc1b6c4 100644 --- a/tests/Widgets/MessageBox.cpp +++ b/tests/Widgets/MessageBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Panel.cpp b/tests/Widgets/Panel.cpp index 49674abb3..4e2642996 100644 --- a/tests/Widgets/Panel.cpp +++ b/tests/Widgets/Panel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/PanelListBox.cpp b/tests/Widgets/PanelListBox.cpp index d287249d4..2163a1307 100644 --- a/tests/Widgets/PanelListBox.cpp +++ b/tests/Widgets/PanelListBox.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Picture.cpp b/tests/Widgets/Picture.cpp index da5505b92..c2e82d8a6 100644 --- a/tests/Widgets/Picture.cpp +++ b/tests/Widgets/Picture.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ProgressBar.cpp b/tests/Widgets/ProgressBar.cpp index 6d42ed2d9..071c5e67e 100644 --- a/tests/Widgets/ProgressBar.cpp +++ b/tests/Widgets/ProgressBar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/RadioButton.cpp b/tests/Widgets/RadioButton.cpp index 4e1d5c19e..ba96e9d24 100644 --- a/tests/Widgets/RadioButton.cpp +++ b/tests/Widgets/RadioButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/RadioButtonGroup.cpp b/tests/Widgets/RadioButtonGroup.cpp index eeac2bc34..5d487af00 100644 --- a/tests/Widgets/RadioButtonGroup.cpp +++ b/tests/Widgets/RadioButtonGroup.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/RangeSlider.cpp b/tests/Widgets/RangeSlider.cpp index 6c1141fc1..ea0500f68 100644 --- a/tests/Widgets/RangeSlider.cpp +++ b/tests/Widgets/RangeSlider.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/RichTextLabel.cpp b/tests/Widgets/RichTextLabel.cpp index 3c299e81d..bcad97198 100644 --- a/tests/Widgets/RichTextLabel.cpp +++ b/tests/Widgets/RichTextLabel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ScrollablePanel.cpp b/tests/Widgets/ScrollablePanel.cpp index 45fd23b47..9f0bdabd1 100644 --- a/tests/Widgets/ScrollablePanel.cpp +++ b/tests/Widgets/ScrollablePanel.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Scrollbar.cpp b/tests/Widgets/Scrollbar.cpp index 7835d042b..03c57c1fb 100644 --- a/tests/Widgets/Scrollbar.cpp +++ b/tests/Widgets/Scrollbar.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/SeparatorLine.cpp b/tests/Widgets/SeparatorLine.cpp index e61759027..34c13e0dd 100644 --- a/tests/Widgets/SeparatorLine.cpp +++ b/tests/Widgets/SeparatorLine.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Slider.cpp b/tests/Widgets/Slider.cpp index 9f3701c3a..14150c74f 100644 --- a/tests/Widgets/Slider.cpp +++ b/tests/Widgets/Slider.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/SpinButton.cpp b/tests/Widgets/SpinButton.cpp index 99b31946d..d056eac81 100644 --- a/tests/Widgets/SpinButton.cpp +++ b/tests/Widgets/SpinButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/SpinControl.cpp b/tests/Widgets/SpinControl.cpp index b8670fe71..0b62e4cc5 100644 --- a/tests/Widgets/SpinControl.cpp +++ b/tests/Widgets/SpinControl.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/SplitContainer.cpp b/tests/Widgets/SplitContainer.cpp index 04e3145f6..8afbd7974 100644 --- a/tests/Widgets/SplitContainer.cpp +++ b/tests/Widgets/SplitContainer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/TabContainer.cpp b/tests/Widgets/TabContainer.cpp index d87db7363..822ca696d 100644 --- a/tests/Widgets/TabContainer.cpp +++ b/tests/Widgets/TabContainer.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/Tabs.cpp b/tests/Widgets/Tabs.cpp index b8a67893c..a4cd7ccab 100644 --- a/tests/Widgets/Tabs.cpp +++ b/tests/Widgets/Tabs.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/TextArea.cpp b/tests/Widgets/TextArea.cpp index 434578a23..0a6f0e422 100644 --- a/tests/Widgets/TextArea.cpp +++ b/tests/Widgets/TextArea.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/ToggleButton.cpp b/tests/Widgets/ToggleButton.cpp index 06025cda4..c8ae402f6 100644 --- a/tests/Widgets/ToggleButton.cpp +++ b/tests/Widgets/ToggleButton.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/TreeView.cpp b/tests/Widgets/TreeView.cpp index 246d78925..0a07ffad4 100644 --- a/tests/Widgets/TreeView.cpp +++ b/tests/Widgets/TreeView.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tests/Widgets/VerticalLayout.cpp b/tests/Widgets/VerticalLayout.cpp index ffd5433fd..2cfdf01dc 100644 --- a/tests/Widgets/VerticalLayout.cpp +++ b/tests/Widgets/VerticalLayout.cpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TGUI - Texus' Graphical User Interface -// Copyright (C) 2012-2024 Bruno Van de Velde (vdv_b@tgui.eu) +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. From ff8d8cd0ae43e8156b2ecc74a482de8ecbb1f6d9 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 16 Jan 2025 18:27:32 +0100 Subject: [PATCH 26/87] Gui Builder should include 'SDL3/SDL_main.h' instead of 'SDL_main.h' when using SDL3 (fixes #250) --- gui-builder/src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gui-builder/src/main.cpp b/gui-builder/src/main.cpp index afb58f82d..1d2b462f6 100644 --- a/gui-builder/src/main.cpp +++ b/gui-builder/src/main.cpp @@ -33,7 +33,11 @@ #if !TGUI_HAS_BACKEND_SFML_GRAPHICS && !TGUI_HAS_BACKEND_SFML_OPENGL3 \ && (TGUI_HAS_BACKEND_SDL_RENDERER || TGUI_HAS_BACKEND_SDL_OPENGL3 || TGUI_HAS_BACKEND_SDL_GLES2 || TGUI_HAS_BACKEND_SDL_TTF_OPENGL3 || TGUI_HAS_BACKEND_SDL_TTF_GLES2) #include // To avoid compiler warnings with including SDL_main.h - #include + #if SDL_MAJOR_VERSION >= 3 + #include + #else + #include + #endif #endif #include "GuiBuilder.hpp" From 8814d74214d36e18c116e479c5a80ddded2fb385 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 16 Jan 2025 19:06:47 +0100 Subject: [PATCH 27/87] Make certain the correct CMake version is installed when building for Android in CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfef8cb40..7793b6994 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -909,6 +909,7 @@ jobs: mkdir SDL2_ttf wget -nv -O- "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$SDL_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL2 wget -nv -O- "https://github.com/libsdl-org/SDL_ttf/releases/download/release-$SDL_TTF_VERSION/SDL2_ttf-$SDL_TTF_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL2_ttf + echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "cmake;3.22.1" - name: Build SDL_RENDERER project working-directory: TGUI/examples/android/SDL_RENDERER @@ -951,6 +952,7 @@ jobs: - name: Install Android NDK run: | echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "ndk;26.1.10909125" + echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "cmake;3.22.1" ANDROID_NDK_ROOT=$(echo $ANDROID_SDK_ROOT/ndk/26.1.10909125) echo "ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT" >> $GITHUB_ENV From 5d9ff2a5c6d39eb29b34e3564fcf4adf05c307c4 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sat, 25 Jan 2025 22:28:57 +0100 Subject: [PATCH 28/87] Added BackendGuiSFML::handleWindowEvents for SFML 3 as alternative to polling events, to provide a similar interface to window.handleEvents --- changelog.md | 1 + doc/doxyfile.in | 1 + .../Backend/Window/SFML/BackendGuiSFML.hpp | 114 ++++++++++++++++++ tests/BackendEvents.cpp | 15 +++ 4 files changed, 131 insertions(+) diff --git a/changelog.md b/changelog.md index b3cebaaf8..a1947d184 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ TGUI 1.8 (TBD) --------------- - New widget: ContextMenu +- Added handleWindowEvents function to SFML backend (only for SFML 3) TGUI 1.7 (22 December 2024) diff --git a/doc/doxyfile.in b/doc/doxyfile.in index 6e357b61a..e9a57b4c7 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -88,6 +88,7 @@ PREDEFINED = TGUI_DEPRECATED(x)= \ TGUI_HAS_BACKEND_GLFW_OPENGL3=1 \ TGUI_HAS_BACKEND_GLFW_GLES2=1 \ TGUI_HAS_BACKEND_RAYLIB=1 \ + SFML_VERSION_MAJOR=3 \ TGUI_NODISCARD=[[nodiscard]] SHOW_NAMESPACES = NO diff --git a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp index d127cfbd0..92ce55eb4 100644 --- a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp +++ b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp @@ -78,10 +78,124 @@ TGUI_MODULE_EXPORT namespace tgui /// gui.handleEvent(*event); /// } /// @endcode + /// + /// If you use SFML 3 and want to use window.handleEvents instead of window.pollEvent or window.waitEvent then + /// check out the handleWindowEvents function instead. + /// + /// @see handleWindowEvents ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool handleEvent(sf::Event event); using BackendGui::handleEvent; +#if SFML_VERSION_MAJOR >= 3 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Handle all pending window events at once using callbacks, as alternative to polling events + /// + /// Using SFML's window.handleEvents directly is not practical in combination with TGUI because the gui needs access to + /// almost all events. You would thus need to have a handler for all event types and call gui.handleEvent in each one. + /// This handleWindowEvents function can be used as alternative to window.handleEvents to do it all for you. + /// + /// Call this function with any amount of parameters, each a callable that takes an event of a certain type as parameter. + /// For each pending event in the window, the callable that takes that event as parameter is called and the handleEvent + /// function is executed (unless the callable returned false). + /// + /// The callables must always take an SFML event as first parameter, but there are 3 variations of allowed handlers: + /// 1) A void function that only takes the event as parameter will be called after gui.handleEvent is executed. + /// 2) A void function with the event as first parameter and a bool as second parameter will also be called after + /// the gui.handleEvent function finished, but the bool argument will contain the return value of handleEvent. + /// 3) A function that returns a bool and takes the event as parameter will be called before gui.handleEvent is executed. + /// When the handler returns false, the call to handleEvent will be skipped and the gui thus ignores the event. + /// + /// This function is not blocking: if there's no pending event then it will return without calling any of the handlers. + /// + /// Usage: + /// @code + /// gui.handleWindowEvents( + /// // A function that returns nothing will be called after the gui has handled the event + /// [](const sf::Event::Closed&) { }, + /// + /// // The function can take an optional extra parameter that indicates whether the gui processed the event. + /// // The value of the boolean is what gets returned by the handleEvent function that is called internally. + /// [](sf::Event::TextEntered&, bool /*consumedByGui*/) { }, + /// + /// // If you don't want the gui to process some events, you can let the function return a bool. + /// // In this case, the function will be called earlier and the return value determines if TGUI handles the event or ignores it. + /// // The handleEvent function will only be called when the function returns true. + /// [](sf::Event::MouseMoved) { return false; }, + /// + /// // Generic lambdas are also supported. Note that multiple matching functions can be executed for the same event, + /// // so this generic lambda is still called for Closed events even though a lambda above is also executed for Closed events. + /// [](auto&& event) { + /// if constexpr (std::is_same_v, sf::Event::MouseButtonReleased>) + /// return false; + /// else + /// return true; + /// } + /// ); + /// @endcode + /// + /// @warning Multiple handlers may be called for the same event, because every handler with the right parameter type gets called. + /// + /// @see handleEvent + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + template + void handleWindowEvents(Ts&&... handlers) + { + if (!m_window) + return; + + m_window->handleEvents([this,&handlers...](auto&& event) { + using EventType = decltype(event); + + // We can't properly detect whether the handlers are valid (e.g. when using an invalid event type), + // but we can do some tests that will give errors on handlers that are wrong but almost correct. + static_assert(!std::disjunction_v...>, "Handler for handleWindowEvents can't have both an extra bool argument and a bool return type"); + + // If any of the handlers return a bool then they will be executed before the event is passed to the gui. + // The returned boolean then decides whether the gui should still process the event or not. + // Only one of the handlers should match at most, but letting the compiler figure out which handler to + // call by creating an overload set is tricky because only handlers with a bool returns should be called here. + auto callIfMatchesAndReturnsBool = [&event](auto&& handler) + { + // std::is_invocable_r_v would still return true if the type is convertable to bool, so we use std::invoke_result_t to test the return type + using FuncType = decltype(handler); + if constexpr (std::is_invocable_v) + { + if constexpr (std::is_same_v, bool>) + return std::invoke(std::forward(handler), std::forward(event)); + else + { + static_assert(std::is_same_v, void>, "Handler for handleWindowEvents must have either 'void' or 'bool' return type"); + return true; + } + } + else + return true; + }; + const bool passEventToGui = (callIfMatchesAndReturnsBool(std::forward(handlers)) && ...); + + // Let the gui handle the event + bool eventHandledByGui = false; + if (passEventToGui) + eventHandledByGui = handleEvent(std::forward(event)); + + // After the gui has handled the events, we call the handlers that return nothing. + // These handlers can have an optional bool parameter that indicates whether the event was processed by the gui. + auto callIfMatchesAndReturnsVoid = [&event](auto&& handler, auto&&... extraArgs) + { + using FuncType = decltype(handler); + if constexpr (std::is_invocable_v) + { + if constexpr (std::is_same_v, void>) + std::invoke(std::forward(handler), std::forward(event), std::forward(extraArgs)...); + } + }; + (callIfMatchesAndReturnsVoid(std::forward(handlers)), ...); + (callIfMatchesAndReturnsVoid(std::forward(handlers), eventHandledByGui), ...); + }); + } +#endif + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Give the gui control over the main loop /// diff --git a/tests/BackendEvents.cpp b/tests/BackendEvents.cpp index af04ef057..c295a5a58 100644 --- a/tests/BackendEvents.cpp +++ b/tests/BackendEvents.cpp @@ -79,6 +79,21 @@ TEST_CASE("[Backend events]") { SECTION("SFML") { +#if SFML_VERSION_MAJOR >= 3 + SECTION("handleWindowEvents") + { + // We can't test whether the functions get called correctly (as that would require + // controlling the events that exist in the window), but we can at least verify + // that our example code actually compiles. + backendGuiSFML->handleWindowEvents( + [](const sf::Event::Closed&) { }, + [](sf::Event::TextEntered&, bool) { }, + [](sf::Event::MouseMoved) { return false; }, + [](auto&&) {} + ); + } +#endif + SECTION("KeyPressed") { #if SFML_VERSION_MAJOR >= 3 From 4c918cddab36ca2d280e8cf8b99150f46f2e8965 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 26 Jan 2025 10:29:44 +0100 Subject: [PATCH 29/87] Use the new ContextMenu in Gui Builder instead of using a ListBox --- gui-builder/include/GuiBuilder.hpp | 3 +- gui-builder/src/GuiBuilder.cpp | 69 +++++++++--------------------- 2 files changed, 22 insertions(+), 50 deletions(-) diff --git a/gui-builder/include/GuiBuilder.hpp b/gui-builder/include/GuiBuilder.hpp index efe9e05a2..c51c9ce5f 100644 --- a/gui-builder/include/GuiBuilder.hpp +++ b/gui-builder/include/GuiBuilder.hpp @@ -124,7 +124,6 @@ class GuiBuilder void changeWidgetName(const tgui::String& name); void initSelectedWidgetComboBoxAfterLoad(); void removeSelectedWidget(); - void removePopupMenu(); void createNewForm(tgui::String filename); bool loadForm(tgui::String filename, bool loadingFromFile = true); void displayErrorMessage(const tgui::String& error); @@ -186,7 +185,7 @@ class GuiBuilder tgui::ComboBox::Ptr m_selectedWidgetComboBox; tgui::MenuBar::Ptr m_menuBar; tgui::TreeView::Ptr m_widgetHierarchyTree; - tgui::ListBox::Ptr m_popupMenu; + tgui::ContextMenu::Ptr m_popupMenu; std::vector> m_forms; Form* m_selectedForm = nullptr; diff --git a/gui-builder/src/GuiBuilder.cpp b/gui-builder/src/GuiBuilder.cpp index e00cb3f38..5758b18dc 100644 --- a/gui-builder/src/GuiBuilder.cpp +++ b/gui-builder/src/GuiBuilder.cpp @@ -407,38 +407,14 @@ void GuiBuilder::mainLoop() } else if (event.mouseButton.button == tgui::Event::MouseButton::Right) { - if (m_popupMenu) + if (m_selectedForm->rightMouseClick({event.mouseButton.x, event.mouseButton.y})) { - removePopupMenu(); - } - else if (m_selectedForm->rightMouseClick({event.mouseButton.x, event.mouseButton.y})) - { - auto panel = tgui::Panel::create({"100%", "100%"}); - panel->getRenderer()->setBackgroundColor(tgui::Color::Transparent); - m_gui->add(panel); - - m_popupMenu = tgui::ListBox::create(); - panel->add(m_popupMenu); - if (m_selectedForm->getSelectedWidget()) + if (!m_popupMenu) { - m_popupMenu->addItem("Bring to front"); - m_popupMenu->addItem("Send to back"); - m_popupMenu->addItem("Cut"); - m_popupMenu->addItem("Copy"); - } - if (!m_copiedWidgets.empty()) - m_popupMenu->addItem("Paste"); - if (m_selectedForm->getSelectedWidget()) - m_popupMenu->addItem("Delete"); + m_popupMenu = tgui::ContextMenu::create(); + m_gui->add(m_popupMenu); - if (m_popupMenu->getItemCount() > 0) - { - const tgui::Outline outline = m_popupMenu->getSharedRenderer()->getPadding() + m_popupMenu->getSharedRenderer()->getBorders(); - m_popupMenu->setPosition({static_cast(event.mouseButton.x), static_cast(event.mouseButton.y)}); - m_popupMenu->setSize({150, (m_popupMenu->getItemHeight() * m_popupMenu->getItemCount()) + outline.getTop() + outline.getBottom()}); - - panel->onClick([this]{ removePopupMenu(); }); - m_popupMenu->onMouseRelease([this](const tgui::String& item){ + m_popupMenu->onMenuItemClick([this](const tgui::String& item){ if (item == "Bring to front") menuBarCallbackBringWidgetToFront(); else if (item == "Send to back") @@ -451,12 +427,24 @@ void GuiBuilder::mainLoop() menuBarCallbackPasteWidget(); else if (item == "Delete") menuBarCallbackDeleteWidget(); - - tgui::Timer::scheduleCallback([this]{ removePopupMenu(); }); }); } - else // The popup menu is empty - removePopupMenu(); + + m_popupMenu->removeAllMenuItems(); + if (m_selectedForm->getSelectedWidget()) + { + m_popupMenu->addMenuItem("Bring to front"); + m_popupMenu->addMenuItem("Send to back"); + m_popupMenu->addMenuItem("Cut"); + m_popupMenu->addMenuItem("Copy"); + } + if (!m_copiedWidgets.empty()) + m_popupMenu->addMenuItem("Paste"); + if (m_selectedForm->getSelectedWidget()) + m_popupMenu->addMenuItem("Delete"); + + if (!m_popupMenu->getMenuItems().empty()) + m_popupMenu->openMenu({static_cast(event.mouseButton.x), static_cast(event.mouseButton.y)}); } } } @@ -1397,21 +1385,6 @@ void GuiBuilder::removeSelectedWidget() ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void GuiBuilder::removePopupMenu() -{ - if (!m_popupMenu) - return; - - // Remove the popup menu and the transparent panel behind it - m_popupMenu->getParent()->getParent()->remove(m_popupMenu->getParent()->shared_from_this()); - m_popupMenu = nullptr; - - if (m_selectedForm) - m_selectedForm->focus(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void GuiBuilder::createNewForm(tgui::String filename) { // If the filename is an absolute path that contains the resource path then make it relative From 9d167b108d20d388729ac9e2b70afc83d66f91aa Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 26 Jan 2025 10:31:32 +0100 Subject: [PATCH 30/87] ContextMenu should inherit TextColorDisabled from theme --- src/Loading/Theme.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Loading/Theme.cpp b/src/Loading/Theme.cpp index 77c5edead..9a275bcb3 100644 --- a/src/Loading/Theme.cpp +++ b/src/Loading/Theme.cpp @@ -408,6 +408,7 @@ namespace tgui {"BackgroundColor", ""}, {"SelectedBackgroundColor", ""}, {"TextColor", ""}, + {"TextColorDisabled", ""}, {"SelectedTextColor", ""}, {"SeparatorColor", "BorderColor"}, }}, From 39ffbe8daf6e6920ce981e4ae50ef530eb242446 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 26 Jan 2025 10:34:43 +0100 Subject: [PATCH 31/87] Added default value for TextColorDisabled in Black theme --- themes/Black.txt | 1 + themes/development/Black/Black.txt.in | 1 + 2 files changed, 2 insertions(+) diff --git a/themes/Black.txt b/themes/Black.txt index f6a39e69c..6297db14a 100644 --- a/themes/Black.txt +++ b/themes/Black.txt @@ -1,5 +1,6 @@ TextColor = rgb(190, 190, 190); TextColorHover = rgb(250, 250, 250); +TextColorDisabled = rgb(125, 125, 125); SelectedTextColor = White; BorderColor = Black; BackgroundColor = rgb(80, 80, 80); diff --git a/themes/development/Black/Black.txt.in b/themes/development/Black/Black.txt.in index e80119388..95dbc2d11 100644 --- a/themes/development/Black/Black.txt.in +++ b/themes/development/Black/Black.txt.in @@ -1,5 +1,6 @@ TextColor = rgb(190, 190, 190); TextColorHover = rgb(250, 250, 250); +TextColorDisabled = rgb(125, 125, 125); SelectedTextColor = White; BorderColor = Black; BackgroundColor = rgb(80, 80, 80); From 533e6f89fde20fa754ab48fcbbbee2fc5e3d806a Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 26 Jan 2025 10:40:47 +0100 Subject: [PATCH 32/87] setTextSize should not be called in the constructor before the renderer is initialized --- src/Widgets/ColorPicker.cpp | 3 ++- src/Widgets/ContextMenu.cpp | 8 ++++---- src/Widgets/Label.cpp | 3 ++- src/Widgets/ListBox.cpp | 10 +++++----- src/Widgets/ListView.cpp | 12 ++++++------ src/Widgets/MenuBar.cpp | 3 ++- src/Widgets/MessageBox.cpp | 3 ++- src/Widgets/Tabs.cpp | 6 +++--- src/Widgets/TextArea.cpp | 14 +++++++------- 9 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/Widgets/ColorPicker.cpp b/src/Widgets/ColorPicker.cpp index 14b8bb269..3f5c66a88 100644 --- a/src/Widgets/ColorPicker.cpp +++ b/src/Widgets/ColorPicker.cpp @@ -202,10 +202,11 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + + setTextSize(getGlobalTextSize()); } setTitleButtons(ChildWindow::TitleButton::None); - setTextSize(getGlobalTextSize()); auto pixels = MakeUniqueForOverwrite(static_cast(colorWheelSize) * colorWheelSize * 4); for (unsigned int y = 0; y < colorWheelSize; ++y) diff --git a/src/Widgets/ContextMenu.cpp b/src/Widgets/ContextMenu.cpp index 00af6c018..f285c5cb7 100644 --- a/src/Widgets/ContextMenu.cpp +++ b/src/Widgets/ContextMenu.cpp @@ -48,11 +48,11 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); - } - setTextSize(getGlobalTextSize()); - setItemHeight(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f)); - setMinimumMenuWidth((Text::getLineHeight(m_fontCached, m_textSizeCached) * 4) + (2 * m_distanceToSideCached)); + setTextSize(getGlobalTextSize()); + setItemHeight(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f)); + setMinimumMenuWidth((Text::getLineHeight(m_fontCached, m_textSizeCached) * 4) + (2 * m_distanceToSideCached)); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/Label.cpp b/src/Widgets/Label.cpp index abf71e7ec..6568b19f7 100644 --- a/src/Widgets/Label.cpp +++ b/src/Widgets/Label.cpp @@ -46,11 +46,12 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + + setTextSize(getGlobalTextSize()); } m_scrollbar->setVisible(false); // Never shown when AutoSize is true m_scrollbar->setScrollAmount(m_textSizeCached); - setTextSize(getGlobalTextSize()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/ListBox.cpp b/src/Widgets/ListBox.cpp index 63b519647..796612677 100644 --- a/src/Widgets/ListBox.cpp +++ b/src/Widgets/ListBox.cpp @@ -45,12 +45,12 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); - } - setTextSize(getGlobalTextSize()); - setItemHeight(static_cast(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f))); - setSize({Text::getLineHeight(m_fontCached, m_textSizeCached) * 10, - (m_itemHeight * 7) + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + setTextSize(getGlobalTextSize()); + setItemHeight(static_cast(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f))); + setSize({Text::getLineHeight(m_fontCached, m_textSizeCached) * 10, + (m_itemHeight * 7) + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/ListView.cpp b/src/Widgets/ListView.cpp index 5e8710392..6b9b45850 100644 --- a/src/Widgets/ListView.cpp +++ b/src/Widgets/ListView.cpp @@ -52,13 +52,13 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); - } - setTextSize(getGlobalTextSize()); - setItemHeight(static_cast(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f))); - setSize({m_itemHeight * 12, - getHeaderHeight() + getHeaderSeparatorHeight() + (m_itemHeight * 6) - + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + setTextSize(getGlobalTextSize()); + setItemHeight(static_cast(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f))); + setSize({m_itemHeight * 12, + getHeaderHeight() + getHeaderSeparatorHeight() + (m_itemHeight * 6) + + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/MenuBar.cpp b/src/Widgets/MenuBar.cpp index d4cab6c99..da108058c 100644 --- a/src/Widgets/MenuBar.cpp +++ b/src/Widgets/MenuBar.cpp @@ -48,9 +48,10 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + + setTextSize(getGlobalTextSize()); } - setTextSize(getGlobalTextSize()); setMinimumSubMenuWidth((Text::getLineHeight(m_fontCached, m_textSizeCached) * 4) + (2 * m_distanceToSideCached)); setSize({"100%", std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f)}); } diff --git a/src/Widgets/MessageBox.cpp b/src/Widgets/MessageBox.cpp index 007e97135..e5f308ca9 100644 --- a/src/Widgets/MessageBox.cpp +++ b/src/Widgets/MessageBox.cpp @@ -45,10 +45,11 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); + + setTextSize(getGlobalTextSize()); } setTitleButtons(ChildWindow::TitleButton::None); - setTextSize(getGlobalTextSize()); add(m_label, "#TGUI_INTERNAL$MessageBoxText#"); m_label->setTextSize(m_textSizeCached); diff --git a/src/Widgets/Tabs.cpp b/src/Widgets/Tabs.cpp index 69d0fd6eb..228c7e5e0 100644 --- a/src/Widgets/Tabs.cpp +++ b/src/Widgets/Tabs.cpp @@ -47,10 +47,10 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); - } - setTextSize(getGlobalTextSize()); - setTabHeight(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f) + m_bordersCached.getTop() + m_bordersCached.getBottom()); + setTextSize(getGlobalTextSize()); + setTabHeight(std::round(Text::getLineHeight(m_fontCached, m_textSizeCached) * 1.25f) + m_bordersCached.getTop() + m_bordersCached.getBottom()); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/TextArea.cpp b/src/Widgets/TextArea.cpp index 0e3df7bdb..0e501ad76 100644 --- a/src/Widgets/TextArea.cpp +++ b/src/Widgets/TextArea.cpp @@ -56,14 +56,14 @@ namespace tgui { m_renderer = aurora::makeCopied(); setRenderer(Theme::getDefault()->getRendererNoThrow(m_type)); - } - setTextSize(getGlobalTextSize()); - setSize({Text::getLineHeight(m_fontCached, m_textSizeCached) * 18, - 10 * m_fontCached.getLineSpacing(m_textSizeCached) - + std::max(m_fontCached.getFontHeight(m_textSizeCached), m_fontCached.getLineSpacing(m_textSizeCached)) - m_fontCached.getLineSpacing(m_textSizeCached) - + Text::getExtraVerticalPadding(m_textSizeCached) - + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + setTextSize(getGlobalTextSize()); + setSize({Text::getLineHeight(m_fontCached, m_textSizeCached) * 18, + 10 * m_fontCached.getLineSpacing(m_textSizeCached) + + std::max(m_fontCached.getFontHeight(m_textSizeCached), m_fontCached.getLineSpacing(m_textSizeCached)) - m_fontCached.getLineSpacing(m_textSizeCached) + + Text::getExtraVerticalPadding(m_textSizeCached) + + m_paddingCached.getTop() + m_paddingCached.getBottom() + m_bordersCached.getTop() + m_bordersCached.getBottom()}); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From e86fce2f290dcce9c1d4aef4b5dcc42b824d8e3c Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Mon, 27 Jan 2025 20:13:09 +0100 Subject: [PATCH 33/87] Added onRightClick signal to ListBox --- changelog.md | 1 + .../Backend/Window/SFML/BackendGuiSFML.hpp | 2 + include/TGUI/Widgets/ListBox.hpp | 16 ++++ include/TGUI/Widgets/ListView.hpp | 2 +- include/TGUI/Widgets/TreeView.hpp | 2 +- src/Widgets/ListBox.cpp | 78 +++++++++++++------ 6 files changed, 77 insertions(+), 24 deletions(-) diff --git a/changelog.md b/changelog.md index a1947d184..afa04db07 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ TGUI 1.8 (TBD) - New widget: ContextMenu - Added handleWindowEvents function to SFML backend (only for SFML 3) +- Added onRightClick signal to ListBox TGUI 1.7 (22 December 2024) diff --git a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp index 92ce55eb4..102ef31ec 100644 --- a/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp +++ b/include/TGUI/Backend/Window/SFML/BackendGuiSFML.hpp @@ -137,6 +137,8 @@ TGUI_MODULE_EXPORT namespace tgui /// @warning Multiple handlers may be called for the same event, because every handler with the right parameter type gets called. /// /// @see handleEvent + /// + /// @since TGUI 1.8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template void handleWindowEvents(Ts&&... handlers) diff --git a/include/TGUI/Widgets/ListBox.hpp b/include/TGUI/Widgets/ListBox.hpp index 36a78bf11..c081861db 100644 --- a/include/TGUI/Widgets/ListBox.hpp +++ b/include/TGUI/Widgets/ListBox.hpp @@ -499,6 +499,11 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void leftMouseReleased(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void rightMousePressed(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -614,6 +619,16 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void updateSelectedItem(int item); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Update the hovered item based on a mouse event. The innerPos is the mouse pos relative to the area inside the borders. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setHoveredItemBasedOnMousePos(Vector2f innerPos); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Update the selected (and hovered) item based on a mouse event. The innerPos is relative to the area inside the borders. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSelectedItemBasedOnMousePos(Vector2f innerPos); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Checks whether the scrollbar value was changed and emit the onScroll event if it did ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -641,6 +656,7 @@ TGUI_MODULE_EXPORT namespace tgui SignalItem onMousePress = {"MousePressed"}; //!< The mouse went down on an item. Optional parameter: selected item or its index SignalItem onMouseRelease = {"MouseReleased"}; //!< The mouse was released on one of the items. Optional parameter: selected item or its index SignalItem onDoubleClick = {"DoubleClicked"}; //!< An item was double clicked. Optional parameter: selected item or its index + SignalItem onRightClick = {"RightClicked"}; //!< Right mouse pressed on list box (also fires if not on top of item). Optional parameter: selected item or its index SignalUInt onScroll = {"Scrolled"}; //!< The list was scrolled. Optional parameter: new value of scrollbar ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/TGUI/Widgets/ListView.hpp b/include/TGUI/Widgets/ListView.hpp index 1c4b62021..06bc4f308 100644 --- a/include/TGUI/Widgets/ListView.hpp +++ b/include/TGUI/Widgets/ListView.hpp @@ -1096,7 +1096,7 @@ TGUI_MODULE_EXPORT namespace tgui SignalInt onItemSelect = {"ItemSelected"}; SignalInt onDoubleClick = {"DoubleClicked"}; //!< An item was double clicked. Optional parameter: selected item index - SignalInt onRightClick = {"RightClicked"}; //!< Right mouse clicked. Optional parameter: index of item below mouse (-1 when not on top of item) + SignalInt onRightClick = {"RightClicked"}; //!< Right mouse pressed. Optional parameter: index of item below mouse (-1 when not on top of item) SignalInt onHeaderClick = {"HeaderClicked"}; //!< The header was clicked. Optional parameter: column index ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/TGUI/Widgets/TreeView.hpp b/include/TGUI/Widgets/TreeView.hpp index 4d46b1b1d..96c436ba0 100644 --- a/include/TGUI/Widgets/TreeView.hpp +++ b/include/TGUI/Widgets/TreeView.hpp @@ -569,7 +569,7 @@ TGUI_MODULE_EXPORT namespace tgui SignalItemHierarchy onDoubleClick = {"DoubleClicked"}; //!< A leaf node was double clicked. Optional parameter: selected node SignalItemHierarchy onExpand = {"Expanded"}; //!< A branch node was expanded in the tree view. Optional parameter: expanded node SignalItemHierarchy onCollapse = {"Collapsed"}; //!< A branch node was collapsed in the tree view. Optional parameter: collapsed node - SignalItemHierarchy onRightClick = {"RightClicked"}; //!< A node was right clicked. Optional parameter: node below mouse + SignalItemHierarchy onRightClick = {"RightClicked"}; //!< Right mouse button was pressed on top of a node. Optional parameter: node below mouse ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: diff --git a/src/Widgets/ListBox.cpp b/src/Widgets/ListBox.cpp index 796612677..70577ebd3 100644 --- a/src/Widgets/ListBox.cpp +++ b/src/Widgets/ListBox.cpp @@ -605,6 +605,31 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ListBox::setHoveredItemBasedOnMousePos(Vector2f innerPos) + { + // NOLINTNEXTLINE(bugprone-integer-division) + const int hoveringItem = static_cast(((innerPos.y - (m_itemHeight - (m_scrollbar->getValue() % m_itemHeight))) / m_itemHeight) + (m_scrollbar->getValue() / m_itemHeight) + 1); + if (hoveringItem < static_cast(m_items.size())) + updateHoveringItem(hoveringItem); + else + updateHoveringItem(-1); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void ListBox::setSelectedItemBasedOnMousePos(Vector2f innerPos) + { + setHoveredItemBasedOnMousePos(innerPos); + + if (m_selectedItem != m_hoveringItem) + { + m_possibleDoubleClick = false; + updateSelectedItem(m_hoveringItem); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ListBox::leftMousePressed(Vector2f pos) { pos -= getPosition(); @@ -623,20 +648,7 @@ namespace tgui getInnerSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight(), getInnerSize().y - m_paddingCached.getTop() - m_paddingCached.getBottom()}.contains(pos)) { pos.y -= m_bordersCached.getTop() + m_paddingCached.getTop(); - - // NOLINTNEXTLINE(bugprone-integer-division) - const int hoveringItem = static_cast(((pos.y - (m_itemHeight - (m_scrollbar->getValue() % m_itemHeight))) / m_itemHeight) + (m_scrollbar->getValue() / m_itemHeight) + 1); - if (hoveringItem < static_cast(m_items.size())) - updateHoveringItem(hoveringItem); - else - updateHoveringItem(-1); - - if (m_selectedItem != m_hoveringItem) - { - m_possibleDoubleClick = false; - - updateSelectedItem(m_hoveringItem); - } + setSelectedItemBasedOnMousePos(pos); // Call the MousePress event after the item has already been changed, so that selected item represents the clicked item if (m_selectedItem >= 0) @@ -688,6 +700,33 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ListBox::rightMousePressed(Vector2f pos) + { + pos -= getPosition(); + if (m_scrollbar->isShown() && m_scrollbar->isMouseOnWidget(pos)) + return; + + int itemIndex = -1; + if (FloatRect{m_bordersCached.getLeft() + m_paddingCached.getLeft(), m_bordersCached.getTop() + m_paddingCached.getTop(), + getInnerSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight(), getInnerSize().y - m_paddingCached.getTop() - m_paddingCached.getBottom()}.contains(pos)) + { + pos.y -= m_bordersCached.getTop() + m_paddingCached.getTop(); + setSelectedItemBasedOnMousePos(pos); + + itemIndex = m_selectedItem; + } + + if (itemIndex >= 0) + { + const Item& selectedItem = m_items[static_cast(itemIndex)]; + onRightClick.emit(this, itemIndex, selectedItem.text.getString(), selectedItem.id); + } + else + onRightClick.emit(this, -1, "", ""); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ListBox::mouseMoved(Vector2f pos) { pos -= getPosition(); @@ -711,13 +750,7 @@ namespace tgui m_bordersCached.getTop() + m_paddingCached.getTop(), getInnerSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight(), getInnerSize().y - m_paddingCached.getTop() - m_paddingCached.getBottom()}.contains(pos)) { pos.y -= m_bordersCached.getTop() + m_paddingCached.getTop(); - - // NOLINTNEXTLINE(bugprone-integer-division) - int hoveringItem = static_cast(((pos.y - (m_itemHeight - (m_scrollbar->getValue() % m_itemHeight))) / m_itemHeight) + (m_scrollbar->getValue() / m_itemHeight) + 1); - if (hoveringItem < static_cast(m_items.size())) - updateHoveringItem(hoveringItem); - else - updateHoveringItem(-1); + setHoveredItemBasedOnMousePos(pos); // If the mouse is held down then select the item below the mouse if (m_mouseDown && !m_scrollbar->isMouseDown()) @@ -725,7 +758,6 @@ namespace tgui if (m_selectedItem != m_hoveringItem) { m_possibleDoubleClick = false; - updateSelectedItem(m_hoveringItem); } } @@ -808,6 +840,8 @@ namespace tgui return onMouseRelease; else if (signalName == onDoubleClick.getName()) return onDoubleClick; + else if (signalName == onRightClick.getName()) + return onRightClick; else if (signalName == onScroll.getName()) return onScroll; else From fbb5eb3e05557ba1288357f1f1382161620a6a3b Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 2 Feb 2025 18:17:30 +0100 Subject: [PATCH 34/87] Improve the error output when SFML couldn't be found, to inform users about the weird failure when setting SFML_DIR to the build directory (to prevent more reports like issue #251) --- cmake/Dependencies.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 67e1f524e..9d3aeca66 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -64,6 +64,7 @@ macro(tgui_find_dependency_sfml component optional_quiet) message(NOTICE "\nSearching for SFML 2...\n") find_package(SFML 2 CONFIG COMPONENTS ${lowercase_component}) + set(SFML_DIR ${sfml_dir_original}) message(NOTICE "\nSearching for SFML 3...\n") find_package(SFML 3 CONFIG COMPONENTS ${component}) endif() @@ -77,9 +78,11 @@ macro(tgui_find_dependency_sfml component optional_quiet) # find_package couldn't find SFML if(NOT SFML_FOUND) set(SFML_DIR "" CACHE PATH "Path to SFMLConfig.cmake") + message(STATUS "") message(FATAL_ERROR "CMake couldn't find SFML.\n" - "Set SFML_DIR to the directory containing SFMLConfig.cmake (usually something like SFML_ROOT/lib/cmake/SFML)\n") + "Set SFML_DIR to the directory containing SFMLConfig.cmake (usually SFML_ROOT/lib/cmake/SFML).\n" + "If searching for SFML 2 found an SFML 3 config, but searching for SFML 3 failed to find it's Shared/Static configuration, then you are probably attempting to import SFML from its build directory. This is no longer supported in SFML 3, you must install SFML.\n") endif() if (SFML_VERSION VERSION_LESS "2.5.0") From 542c3f140d60d1bad550303495aa42423ca09719 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Mon, 3 Feb 2025 11:51:13 +0100 Subject: [PATCH 35/87] Added openMenuAtMouseCursor function to ContextMenu --- include/TGUI/Backend/Window/BackendGui.hpp | 12 ++++++++++++ include/TGUI/Widgets/ContextMenu.hpp | 11 +++++++++++ src/Backend/Window/BackendGui.cpp | 7 +++++++ src/Widgets/ContextMenu.cpp | 16 ++++++++++++++++ src/Widgets/MenuWidgetBase.cpp | 8 ++++++-- 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/TGUI/Backend/Window/BackendGui.hpp b/include/TGUI/Backend/Window/BackendGui.hpp index bba2b7dc7..5d70b11a3 100644 --- a/include/TGUI/Backend/Window/BackendGui.hpp +++ b/include/TGUI/Backend/Window/BackendGui.hpp @@ -339,6 +339,18 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD Widget::Ptr getWidgetBelowMouseCursor(Vector2i mousePos, bool recursive) const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the mouse position of the last mouse event that was handled by the gui + /// + /// @return Last handled mouse position. In most situations this will the same as the current mouse position on the window. + /// + /// @warning This function returns a value in pixel coordinates. You will need to call mapPixelToCoords to convert it + /// into the coordinate system used by the gui (which is different if its view or viewport was changed). + /// + /// @since TGUI 1.8 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2i getLastMousePosition() const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Focuses the next widget in the gui /// diff --git a/include/TGUI/Widgets/ContextMenu.hpp b/include/TGUI/Widgets/ContextMenu.hpp index 734be7160..691bc9d75 100644 --- a/include/TGUI/Widgets/ContextMenu.hpp +++ b/include/TGUI/Widgets/ContextMenu.hpp @@ -108,9 +108,20 @@ TGUI_MODULE_EXPORT namespace tgui /// The context menu will render nothing until this function is called. /// Once the user clicked an item in the menu, the menu will be closed and you need to call this function again in order /// for the menu to become visible again. + /// + /// @see openMenuAtCursor ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void openMenu(Vector2f position); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Opens the context menu at the last mouse cursor position + /// + /// The context menu will render nothing until this function is called. + /// Once the user clicked an item in the menu, the menu will be closed and you need to call this function again in order + /// for the menu to become visible again. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void openMenuAtMouseCursor(); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Closes the context menu if it was open ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Backend/Window/BackendGui.cpp b/src/Backend/Window/BackendGui.cpp index e26f15df5..6234f597f 100644 --- a/src/Backend/Window/BackendGui.cpp +++ b/src/Backend/Window/BackendGui.cpp @@ -354,6 +354,13 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Vector2i BackendGui::getLastMousePosition() const + { + return m_lastMousePos; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool BackendGui::focusNextWidget(bool recursive) { return m_container->focusNextWidget(recursive); diff --git a/src/Widgets/ContextMenu.cpp b/src/Widgets/ContextMenu.cpp index f285c5cb7..40dc1d735 100644 --- a/src/Widgets/ContextMenu.cpp +++ b/src/Widgets/ContextMenu.cpp @@ -24,6 +24,7 @@ #include #include +#include #if !TGUI_EXPERIMENTAL_USE_STD_MODULE #include @@ -136,6 +137,21 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ContextMenu::openMenuAtMouseCursor() + { + auto position = m_position; + if (m_parentGui) + { + const Vector2f lastMousePos = m_parentGui->mapPixelToCoords(m_parentGui->getLastMousePosition()); + position = lastMousePos - getAbsolutePosition(-getPosition()); + } + + setPosition(position); + openMenu(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ContextMenu::closeMenu() { if (!m_menuOpen) diff --git a/src/Widgets/MenuWidgetBase.cpp b/src/Widgets/MenuWidgetBase.cpp index c2e3ccd72..a20906c8e 100644 --- a/src/Widgets/MenuWidgetBase.cpp +++ b/src/Widgets/MenuWidgetBase.cpp @@ -24,6 +24,7 @@ #include #include +#include #if !TGUI_EXPERIMENTAL_USE_STD_MODULE #include @@ -972,7 +973,7 @@ namespace tgui Vector2f OpenMenuPlaceholder::getFullSize() const { if (m_parent) - return m_parent->getInnerSize() - getPosition(); + return m_parent->getInnerSize() + getWidgetOffset(); else return {0, 0}; } @@ -981,7 +982,10 @@ namespace tgui Vector2f OpenMenuPlaceholder::getWidgetOffset() const { - return -getPosition(); + if (m_parentGui) + return m_parentGui->getView().getPosition() - getPosition(); + else + return -getPosition(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 53aea36db5723f78cf6ddb2e97f60459eb25ed7d Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 9 Feb 2025 10:23:01 +0100 Subject: [PATCH 36/87] Updated documentation templates --- doc/doxyfile.in | 5 +++++ doc/doxygen-awesome.css | 10 +++++++-- doc/footer.html | 13 +++++------ doc/header.html | 48 ++++++++++++++++++++++++++++++----------- 4 files changed, 54 insertions(+), 22 deletions(-) mode change 100644 => 100755 doc/doxygen-awesome.css diff --git a/doc/doxyfile.in b/doc/doxyfile.in index e9a57b4c7..5e69601fe 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -14,6 +14,11 @@ GENERATE_TESTLIST = NO GENERATE_BUGLIST = NO GENERATE_DEPRECATEDLIST= YES +GENERATE_TREEVIEW = YES +DISABLE_INDEX = NO +FULL_SIDEBAR = NO +HTML_COLORSTYLE = LIGHT + INPUT = "@PROJECT_SOURCE_DIR@/include/TGUI" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Loading" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Widgets" \ diff --git a/doc/doxygen-awesome.css b/doc/doxygen-awesome.css old mode 100644 new mode 100755 index a2715e268..af68d5fea --- a/doc/doxygen-awesome.css +++ b/doc/doxygen-awesome.css @@ -32,6 +32,7 @@ html { --primary-color: #1779c4; --primary-dark-color: #335c80; --primary-light-color: #70b1e9; + --on-primary-color: #ffffff; /* page base colors */ --page-background-color: #ffffff; @@ -113,7 +114,7 @@ html { */ --menu-display: block; - --menu-focus-foreground: var(--page-background-color); + --menu-focus-foreground: var(--on-primary-color); --menu-focus-background: var(--primary-color); --menu-selected-background: rgba(0,0,0,.05); @@ -805,6 +806,8 @@ html.dark-mode iframe#MSearchResults { #nav-tree .item { height: var(--tree-item-height); line-height: var(--tree-item-height); + overflow: hidden; + text-overflow: ellipsis; } #nav-tree .item > a:focus { @@ -823,6 +826,8 @@ html.dark-mode iframe#MSearchResults { background-image: none; background-color: transparent; position: relative; + color: var(--primary-color) !important; + font-weight: 500; } #nav-tree .selected::after { @@ -940,6 +945,7 @@ td.memSeparator { span.mlabel { background: var(--primary-color); + color: var(--on-primary-color); border: none; padding: 4px 9px; border-radius: 12px; @@ -1749,7 +1755,7 @@ table.fieldtable th { color: var(--tablehead-foreground); } -table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fielddoc, .fieldtable th { +table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fieldinit, .fieldtable td.fielddoc, .fieldtable th { border-bottom: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color); } diff --git a/doc/footer.html b/doc/footer.html index e0a662905..076ec5cbc 100644 --- a/doc/footer.html +++ b/doc/footer.html @@ -1,21 +1,18 @@ - + + @@ -25,7 +22,6 @@ {% include footer.ext %} <{{""}}!{{""}}-{{""}}- --> - + diff --git a/doc/header.html b/doc/header.html index 6fccbbac2..a946a1297 100644 --- a/doc/header.html +++ b/doc/header.html @@ -1,21 +1,33 @@ --- --- - - - + + + - - + + $projectname: $title $title + + + + + + + + + + + $treeview $search $mathjax +$darkmode $extrastylesheet @@ -71,37 +83,49 @@ <{{""}}!-- {% raw %} --> + + +
+ + +
- + - + - - - + + + + + + + +
-
$projectname -  $projectnumber +
+
$projectname $projectnumber
$projectbrief
+
$projectbrief
$searchbox$searchbox
$searchbox
From 358702461175373bdad4f9da163e1463d4d3f651 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 9 Feb 2025 10:34:32 +0100 Subject: [PATCH 37/87] Enable c++17 code in nightly builds (which can be done without issues as c++17 is already a requirement for SFML 3) --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7793b6994..1f01ace49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1157,7 +1157,7 @@ jobs: -DSFML_DIR="${env:GITHUB_WORKSPACE}/x86/SFML-${env:SFML_VERSION}/lib/cmake/SFML/" -DCMAKE_UNITY_BUILD=ON -DBUILD_SHARED_LIBS=OFF - -DTGUI_CXX_STANDARD=14 + -DTGUI_CXX_STANDARD=17 -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_DOC=ON -DTGUI_BUILD_EXAMPLES=OFF @@ -1176,7 +1176,7 @@ jobs: -DSFML_DIR="${env:GITHUB_WORKSPACE}/x64/SFML-${env:SFML_VERSION}/lib/cmake/SFML/" -DCMAKE_UNITY_BUILD=ON -DBUILD_SHARED_LIBS=OFF - -DTGUI_CXX_STANDARD=14 + -DTGUI_CXX_STANDARD=17 -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_DOC=ON -DTGUI_BUILD_EXAMPLES=OFF @@ -1195,7 +1195,7 @@ jobs: -DSFML_DIR="${env:GITHUB_WORKSPACE}/x86/SFML-${env:SFML_VERSION}/lib/cmake/SFML/" -DCMAKE_UNITY_BUILD=ON -DBUILD_SHARED_LIBS=ON - -DTGUI_CXX_STANDARD=14 + -DTGUI_CXX_STANDARD=17 -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_EXAMPLES=OFF -DTGUI_BUILD_GUI_BUILDER=OFF @@ -1213,7 +1213,7 @@ jobs: -DSFML_DIR="${env:GITHUB_WORKSPACE}/x64/SFML-${env:SFML_VERSION}/lib/cmake/SFML/" -DCMAKE_UNITY_BUILD=ON -DBUILD_SHARED_LIBS=ON - -DTGUI_CXX_STANDARD=14 + -DTGUI_CXX_STANDARD=17 -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_EXAMPLES=OFF -DTGUI_BUILD_GUI_BUILDER=OFF From 77f7fb077c4a3fed5930b9747d6bf911407b7b54 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 9 Feb 2025 11:39:17 +0100 Subject: [PATCH 38/87] Added Smooth property to CanvasSFML --- .../Renderer/SFML-Graphics/CanvasSFML.hpp | 16 ++++++++++++++++ .../Renderer/SFML-Graphics/CanvasSFML.cpp | 14 ++++++++++++++ tests/Widgets/Canvas.cpp | 8 ++++++++ 3 files changed, 38 insertions(+) diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp index 8bebc114f..f4330567f 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp @@ -170,6 +170,22 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD IntRect getViewport() const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Enable or disable texture smoothing + /// + /// This parameter is disabled by default. + /// + /// @param smooth `true` to enable smoothing, `false` to disable it + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void setSmooth(bool smooth); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Tell whether the smooth filtering is enabled or not + /// + /// @return `true` if texture smoothing is enabled + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD bool isSmooth() const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Clears the entire canvas with a single color /// diff --git a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp index 94ed57784..615034e7f 100644 --- a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp @@ -208,6 +208,20 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void CanvasSFML::setSmooth(bool smooth) + { + m_renderTexture.setSmooth(smooth); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool CanvasSFML::isSmooth() const + { + return m_renderTexture.isSmooth(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void CanvasSFML::clear(Color color) { m_renderTexture.clear({color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()}); diff --git a/tests/Widgets/Canvas.cpp b/tests/Widgets/Canvas.cpp index eae7efff7..603a526ab 100644 --- a/tests/Widgets/Canvas.cpp +++ b/tests/Widgets/Canvas.cpp @@ -133,6 +133,14 @@ TEST_CASE("[CanvasSFML]") REQUIRE(canvas->getViewport() == tgui::IntRect(20, 20, 100, 60)); } + SECTION("Smooth") + { + canvas->setSmooth(true); + REQUIRE(canvas->isSmooth()); + canvas->setSmooth(false); + REQUIRE(!canvas->isSmooth()); + } + SECTION("internal render texture") { canvas = tgui::CanvasSFML::create({50, 50}); From 6ae6732f6c3908fa02d334e2f67a14db4a110c7a Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 9 Feb 2025 18:38:23 +0100 Subject: [PATCH 39/87] Changed the way the view works in CanvasSFML - A custom view is no longer reset when the size of the canvas changes - A resetView function was added to remove a custom view - The internal render texture is resized with the canvas, instead of keeping a larger texture when the canvas shrinks. This makes the object returned by getRenderTexture() more usable. --- changelog.md | 2 + .../Renderer/SFML-Graphics/CanvasSFML.hpp | 29 +++- .../Renderer/SFML-Graphics/CanvasSFML.cpp | 129 ++++++++---------- 3 files changed, 85 insertions(+), 75 deletions(-) diff --git a/changelog.md b/changelog.md index afa04db07..d451648de 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,8 @@ TGUI 1.8 (TBD) - New widget: ContextMenu - Added handleWindowEvents function to SFML backend (only for SFML 3) - Added onRightClick signal to ListBox +- Added setSmooth and isSmooth to CanvasSFML +- Changed the way the view is handled in CanvasSFML TGUI 1.7 (22 December 2024) diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp index f4330567f..b28bc5b38 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp @@ -125,6 +125,8 @@ TGUI_MODULE_EXPORT namespace tgui /// @brief Changes the size of the widget /// /// @param size The new size of the widget + /// + /// @warning The contents of the canvas needs to be repainted (using clear, draw and display functions) after a resize. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setSize(const Layout2d& size) override; using Widget::setSize; @@ -132,15 +134,17 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Change the current active view /// + /// @param view New view to use + /// /// The view is like a 2D camera, it controls which part of the 2D scene is visible, and how it is viewed in the canvas. /// The new view will affect everything that is drawn, until another view is set. /// The canvas keeps its own copy of the view, so it is not necessary to keep the original one alive after calling /// this function. - /// To restore the original view of the target, you can pass the result of getDefaultView() to this function. /// - /// @warning This view is reset when the size of the canvas is changed. + /// The view set by this function will remain active even after the canvas is resized. + /// To restore the original view of the target, you can call the resetView() function. /// - /// @param view New view to use + /// @see resetView ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setView(const sf::View& view); @@ -151,6 +155,16 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD const sf::View& getView() const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Changes the current active view back to the default value + /// + /// The default view will automatically change when the canvas is resized to keep the view and canvas size the same. + /// If you want to set a fixed view that doesn't change on resize then you should call the setView function. + /// + /// @since TGUI 1.8 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void resetView(); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Get the default view of the canvas /// @@ -176,6 +190,8 @@ TGUI_MODULE_EXPORT namespace tgui /// This parameter is disabled by default. /// /// @param smooth `true` to enable smoothing, `false` to disable it + /// + /// @since TGUI 1.8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setSmooth(bool smooth); @@ -183,6 +199,8 @@ TGUI_MODULE_EXPORT namespace tgui /// @brief Tell whether the smooth filtering is enabled or not /// /// @return `true` if texture smoothing is enabled + /// + /// @since TGUI 1.8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD bool isSmooth() const; @@ -245,7 +263,7 @@ TGUI_MODULE_EXPORT namespace tgui /// /// @return Reference to the internal render texture /// - /// @warning Don't call the create function on the returned render texture. + /// @warning You are not allowed to change the size or view of the returned render texture. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD sf::RenderTexture& getRenderTexture() { @@ -263,9 +281,8 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: - sf::View m_view; sf::RenderTexture m_renderTexture; - Vector2u m_usedTextureSize; + Optional m_customView; }; } diff --git a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp index 615034e7f..e1b1e0348 100644 --- a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp @@ -41,16 +41,15 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CanvasSFML::CanvasSFML(const char* typeName, bool initRenderer) : - CanvasBase{typeName, initRenderer}, - m_view{{{}, {1, 1}}} + CanvasBase{typeName, initRenderer} { } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CanvasSFML::CanvasSFML(const CanvasSFML& other) : - CanvasBase{other}, - m_view {other.m_view} + CanvasBase {other}, + m_customView{other.m_customView} { setSize(other.getSize()); } @@ -58,15 +57,14 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CanvasSFML::CanvasSFML(CanvasSFML&& other) noexcept : - CanvasBase{std::move(other)}, - m_view {std::move(other.m_view)}, + CanvasBase {std::move(other)}, #if SFML_VERSION_MAJOR >= 3 m_renderTexture{std::move(other.m_renderTexture)}, #endif - m_usedTextureSize{std::move(other.m_usedTextureSize)} + m_customView {std::move(other.m_customView)} { #if SFML_VERSION_MAJOR < 3 - setSize(getSize()); // sf::RenderTexture does not support move yet + setSize(getSize()); // sf::RenderTexture did not support move yet #endif } @@ -77,8 +75,7 @@ namespace tgui if (this != &right) { ClickableWidget::operator=(right); - m_view = right.m_view; - m_usedTextureSize = right.m_usedTextureSize; + m_customView = right.m_customView; setSize(right.getSize()); } @@ -92,14 +89,12 @@ namespace tgui if (this != &right) { ClickableWidget::operator=(std::move(right)); - m_view = std::move(right.m_view); - m_usedTextureSize = std::move(right.m_usedTextureSize); + m_customView = std::move(right.m_customView); #if SFML_VERSION_MAJOR >= 3 m_renderTexture = std::move(right.m_renderTexture); #else - // sf::RenderTexture does not support move yet - setSize(getSize()); + setSize(getSize()); // sf::RenderTexture did not support move yet #endif } @@ -135,7 +130,7 @@ namespace tgui if ((newSize.x > 0) && (newSize.y > 0)) { const Vector2u newTextureSize{newSize}; - if ((m_renderTexture.getSize().x < newTextureSize.x) || (m_renderTexture.getSize().y < newTextureSize.y)) + if ((m_renderTexture.getSize().x != newTextureSize.x) || (m_renderTexture.getSize().y != newTextureSize.y)) { #if SFML_VERSION_MAJOR >= 3 (void)m_renderTexture.resize({newTextureSize.x, newTextureSize.y}); @@ -143,55 +138,40 @@ namespace tgui m_renderTexture.create(newTextureSize.x, newTextureSize.y); #endif } - - m_usedTextureSize = newTextureSize; } - setView(getDefaultView()); + if (m_customView.has_value()) + m_renderTexture.setView(m_customView.value()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CanvasSFML::setView(const sf::View& view) { - m_view = view; + m_customView = view; + m_renderTexture.setView(view); + } - // The render texture might be larger than the canvas - sf::FloatRect viewport = view.getViewport(); - if ((m_renderTexture.getSize().x > 0) && (m_renderTexture.getSize().y > 0)) - { - const float scaleX = static_cast(m_usedTextureSize.x) / static_cast(m_renderTexture.getSize().x); - const float scaleY = static_cast(m_usedTextureSize.y) / static_cast(m_renderTexture.getSize().y); -#if SFML_VERSION_MAJOR >= 3 - viewport.position.x *= scaleX; - viewport.position.y *= scaleY; - viewport.size.x *= scaleX; - viewport.size.y *= scaleY; -#else - viewport.left *= scaleX; - viewport.top *= scaleY; - viewport.width *= scaleX; - viewport.height *= scaleY; -#endif - } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - sf::View internalView = view; - internalView.setViewport(viewport); - m_renderTexture.setView(internalView); + const sf::View& CanvasSFML::getView() const + { + return m_renderTexture.getView(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - const sf::View& CanvasSFML::getView() const + void CanvasSFML::resetView() { - return m_view; + m_customView.reset(); + m_renderTexture.setView(getDefaultView()); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sf::View CanvasSFML::getDefaultView() const { - return sf::View{{{}, {static_cast(m_usedTextureSize.x), static_cast(m_usedTextureSize.y)}}}; + return m_renderTexture.getDefaultView(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -295,18 +275,48 @@ namespace tgui void CanvasSFML::draw(BackendRenderTarget& target, RenderStates states) const { + TGUI_ASSERT(dynamic_cast(&target), "CanvasSFML requires a render target of type BackendRenderTargetSFML"); + const Vector2f size = getSize(); - if ((size.x <= 0) || (size.y <= 0) || (m_usedTextureSize.x == 0) || (m_usedTextureSize.y == 0)) + const sf::Texture& texture = m_renderTexture.getTexture(); + const Vector2f textureSize = Vector2f{static_cast(texture.getSize().x), static_cast(texture.getSize().y)}; + if ((size.x <= 0) || (size.y <= 0) || (textureSize.x == 0) || (textureSize.y == 0)) return; - const Vector2f normalizedTextureSize{static_cast(m_usedTextureSize.x) / static_cast(m_renderTexture.getSize().x), - static_cast(m_usedTextureSize.y) / static_cast(m_renderTexture.getSize().y)}; + const std::array& transformMatrix = states.transform.getMatrix(); const Vertex::Color vertexColor(Color::applyOpacity(Color::White, m_opacityCached)); + + sf::RenderStates statesSFML; + statesSFML.texture = &texture; + statesSFML.transform = sf::Transform( + transformMatrix[0], transformMatrix[4], transformMatrix[12], + transformMatrix[1], transformMatrix[5], transformMatrix[13], + transformMatrix[3], transformMatrix[7], transformMatrix[15]); + +#if SFML_VERSION_MAJOR >= 3 + statesSFML.coordinateType = sf::CoordinateType::Normalized; + + // We use textureSize instead of size for the vertices coordinates to keep rendering stable when the size is changing and + // the width and height aren't integer values. + const sf::Color vertexColorSFML{vertexColor.red, vertexColor.green, vertexColor.blue, vertexColor.alpha}; + const std::array verticesSFML = {{ + {{0, 0}, vertexColorSFML, {0, 0}}, + {{0, textureSize.y}, vertexColorSFML, {0, 1}}, + {{textureSize.x, 0}, vertexColorSFML, {1, 0}}, + {{textureSize.x, 0}, vertexColorSFML, {1, 0}}, + {{0, textureSize.y}, vertexColorSFML, {0, 1}}, + {{textureSize.x, textureSize.y}, vertexColorSFML, {1, 1}}, + }}; + + static_cast(target).getTarget()->draw(verticesSFML.data(), verticesSFML.size(), sf::PrimitiveType::Triangles, statesSFML); +#else + // We use textureSize instead of size for the vertices coordinates to keep rendering stable when the size is changing and + // the width and height aren't integer values. const std::array vertices = {{ {{0, 0}, vertexColor, {0, 0}}, - {{size.x, 0}, vertexColor, {normalizedTextureSize.x, 0}}, - {{0, size.y}, vertexColor, {0, normalizedTextureSize.y}}, - {{size.x, size.y}, vertexColor, {normalizedTextureSize.x, normalizedTextureSize.y}}, + {{textureSize.x, 0}, vertexColor, {1, 0}}, + {{0, textureSize.y}, vertexColor, {0, 1}}, + {{textureSize.x, textureSize.y}, vertexColor, {1, 1}}, }}; const std::array indices = {{ 0, 2, 1, @@ -317,16 +327,9 @@ namespace tgui // we will create an array of our own Vertex objects and then use a reinterpret_cast to turn them into sf::Vertex. static_assert(sizeof(Vertex) == sizeof(sf::Vertex), "Size of sf::Vertex has to match with tgui::Vertex for optimization to work"); - const sf::Texture& texture = m_renderTexture.getTexture(); -#if SFML_VERSION_MAJOR < 3 - const Vector2f textureSize = Vector2f{static_cast(texture.getSize().x), static_cast(texture.getSize().y)}; -#endif auto verticesSFML = MakeUniqueForOverwrite(indices.size()); for (std::size_t i = 0; i < indices.size(); ++i) { -#if SFML_VERSION_MAJOR >= 3 - verticesSFML[i] = vertices[indices[i]]; -#else verticesSFML[i].position.x = vertices[indices[i]].position.x; verticesSFML[i].position.y = vertices[indices[i]].position.y; verticesSFML[i].color.red = vertices[indices[i]].color.red; @@ -335,22 +338,10 @@ namespace tgui verticesSFML[i].color.alpha = vertices[indices[i]].color.alpha; verticesSFML[i].texCoords.x = vertices[indices[i]].texCoords.x * textureSize.x; verticesSFML[i].texCoords.y = vertices[indices[i]].texCoords.y * textureSize.y; -#endif } - sf::RenderStates statesSFML; - const std::array& transformMatrix = states.transform.getMatrix(); - statesSFML.texture = &texture; - statesSFML.transform = sf::Transform( - transformMatrix[0], transformMatrix[4], transformMatrix[12], - transformMatrix[1], transformMatrix[5], transformMatrix[13], - transformMatrix[3], transformMatrix[7], transformMatrix[15]); -#if SFML_VERSION_MAJOR >= 3 - statesSFML.coordinateType = sf::CoordinateType::Normalized; -#endif - - TGUI_ASSERT(dynamic_cast(&target), "CanvasSFML requires a render target of type BackendRenderTargetSFML"); static_cast(target).getTarget()->draw(reinterpret_cast(verticesSFML.get()), indices.size(), sf::PrimitiveType::Triangles, statesSFML); +#endif } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 7ee7843c1a80b796ef4e10b69af647a6b4c270bf Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 9 Feb 2025 19:05:16 +0100 Subject: [PATCH 40/87] Pressing escape now closes the menu from ContextMenu or MenuBar --- changelog.md | 1 + include/TGUI/Widgets/MenuWidgetBase.hpp | 5 +++++ src/Widgets/ContextMenu.cpp | 3 +++ src/Widgets/MenuBar.cpp | 3 +++ src/Widgets/MenuWidgetBase.cpp | 8 ++++++++ 5 files changed, 20 insertions(+) diff --git a/changelog.md b/changelog.md index d451648de..ddbb191a7 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,7 @@ TGUI 1.8 (TBD) - Added onRightClick signal to ListBox - Added setSmooth and isSmooth to CanvasSFML - Changed the way the view is handled in CanvasSFML +- Pressing escape now closes the menu from ContextMenu or MenuBar TGUI 1.7 (22 December 2024) diff --git a/include/TGUI/Widgets/MenuWidgetBase.hpp b/include/TGUI/Widgets/MenuWidgetBase.hpp index a96548af5..696b8a921 100644 --- a/include/TGUI/Widgets/MenuWidgetBase.hpp +++ b/include/TGUI/Widgets/MenuWidgetBase.hpp @@ -375,6 +375,11 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void mouseMoved(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void keyPressed(const Event::KeyEvent& event) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Makes a copy of the widget ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/ContextMenu.cpp b/src/Widgets/ContextMenu.cpp index 40dc1d735..a47932f9e 100644 --- a/src/Widgets/ContextMenu.cpp +++ b/src/Widgets/ContextMenu.cpp @@ -124,6 +124,9 @@ namespace tgui m_openMenuPlaceholder->setPosition(getAbsolutePosition()); m_openMenuPlaceholder->setScale(scale); container->add(m_openMenuPlaceholder, "#TGUI_INTERNAL$OpenMenuPlaceholder#"); + + // Steal the focus, to intercept key events and to e.g. prevent typing in an edit box while the menu is open + m_openMenuPlaceholder->setFocused(true); } } diff --git a/src/Widgets/MenuBar.cpp b/src/Widgets/MenuBar.cpp index da108058c..1ac0e5a50 100644 --- a/src/Widgets/MenuBar.cpp +++ b/src/Widgets/MenuBar.cpp @@ -386,6 +386,9 @@ namespace tgui m_openMenuPlaceholder->setPosition(getAbsolutePosition()); m_openMenuPlaceholder->setScale(scale); container->add(m_openMenuPlaceholder, "#TGUI_INTERNAL$OpenMenuPlaceholder#"); + + // Focus the menu itself to handle key events (e.g. escape to close the menu) + m_openMenuPlaceholder->setFocused(true); } } diff --git a/src/Widgets/MenuWidgetBase.cpp b/src/Widgets/MenuWidgetBase.cpp index a20906c8e..8a8d9a9a1 100644 --- a/src/Widgets/MenuWidgetBase.cpp +++ b/src/Widgets/MenuWidgetBase.cpp @@ -1042,6 +1042,14 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void OpenMenuPlaceholder::keyPressed(const Event::KeyEvent& event) + { + if (event.code == Event::KeyboardKey::Escape) + m_menuWidget->closeMenu(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void OpenMenuPlaceholder::draw(BackendRenderTarget& target, RenderStates states) const { m_menuWidget->drawOpenMenu(target, states); From f0421cc9b39c88fb409afcb4a066aae7caa4b063 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 13 Feb 2025 22:23:35 +0100 Subject: [PATCH 41/87] Added onTabRightClick signal to Tabs widget --- changelog.md | 1 + include/TGUI/Widgets/Tabs.hpp | 6 ++++++ src/Widgets/Tabs.cpp | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/changelog.md b/changelog.md index ddbb191a7..f59a554be 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ TGUI 1.8 (TBD) - New widget: ContextMenu - Added handleWindowEvents function to SFML backend (only for SFML 3) - Added onRightClick signal to ListBox +- Added onTabRightClick signal to Tabs - Added setSmooth and isSmooth to CanvasSFML - Changed the way the view is handled in CanvasSFML - Pressing escape now closes the menu from ContextMenu or MenuBar diff --git a/include/TGUI/Widgets/Tabs.hpp b/include/TGUI/Widgets/Tabs.hpp index bfd547d11..a22c1c07a 100644 --- a/include/TGUI/Widgets/Tabs.hpp +++ b/include/TGUI/Widgets/Tabs.hpp @@ -343,6 +343,11 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool leftMousePressed(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void rightMousePressed(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -416,6 +421,7 @@ TGUI_MODULE_EXPORT namespace tgui public: SignalString onTabSelect = {"TabSelected"}; //!< A tab that was selected. Optional parameter: selected item + SignalString onTabRightClick = {"TabRightClicked"}; //!< Right mouse pressed on a tab. Optional parameter: selected item ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: diff --git a/src/Widgets/Tabs.cpp b/src/Widgets/Tabs.cpp index 228c7e5e0..e6e2025f2 100644 --- a/src/Widgets/Tabs.cpp +++ b/src/Widgets/Tabs.cpp @@ -456,6 +456,16 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Tabs::rightMousePressed(Vector2f pos) + { + leftMousePressed(pos); // Select the tab on which you clicked + + if (m_selectedTab >= 0) + onTabRightClick.emit(this, m_tabs[static_cast(m_selectedTab)].text.getString()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Tabs::mouseMoved(Vector2f pos) { Widget::mouseMoved(pos); @@ -555,6 +565,8 @@ namespace tgui { if (signalName == onTabSelect.getName()) return onTabSelect; + else if (signalName == onTabRightClick.getName()) + return onTabRightClick; else return Widget::getSignal(std::move(signalName)); } From 17a6e6bc12963be84bd2ced33c49d529d4e2eca7 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 13 Feb 2025 22:45:51 +0100 Subject: [PATCH 42/87] Don't close the menu from ContextMenu or MenuBar when clicking on a disabled item or on an item that has a submenu --- src/Widgets/MenuWidgetBase.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Widgets/MenuWidgetBase.cpp b/src/Widgets/MenuWidgetBase.cpp index 8a8d9a9a1..fb573ecf5 100644 --- a/src/Widgets/MenuWidgetBase.cpp +++ b/src/Widgets/MenuWidgetBase.cpp @@ -715,18 +715,20 @@ namespace tgui hierarchy.push_back(menu->text.getString()); while (menu->selectedMenuItem >= 0) { - auto& menuItem = menu->menuItems[static_cast(menu->selectedMenuItem)]; - hierarchy.push_back(menuItem.text.getString()); - if (menuItem.menuItems.empty()) + menu = &menu->menuItems[static_cast(menu->selectedMenuItem)]; + hierarchy.push_back(menu->text.getString()); + if (menu->menuItems.empty()) { emit = true; break; } - - menu = &menuItem; } - closeMenu(); + // Close the menu if the mouse went down on a leaf menu item. + // If the item below the mouse is disabled or we clicked on an item that has a submenu then menuItems won't be empty. + if (menu->menuItems.empty()) + closeMenu(); + if (emit) emitMenuItemClick(hierarchy); } @@ -999,7 +1001,10 @@ namespace tgui void OpenMenuPlaceholder::leftMouseButtonNoLongerDown() { - m_menuWidget->leftMouseReleasedOnMenu(); + if (m_mouseHover) + m_menuWidget->leftMouseReleasedOnMenu(); + else + m_menuWidget->closeMenu(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 503965ce775f84714f421360564336d72ada3b7e Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 13 Feb 2025 22:46:34 +0100 Subject: [PATCH 43/87] Close the menu of ContextMenu or MenuBar when right clicking again outside the menu --- include/TGUI/Widgets/MenuWidgetBase.hpp | 5 +++++ src/Widgets/MenuWidgetBase.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/include/TGUI/Widgets/MenuWidgetBase.hpp b/include/TGUI/Widgets/MenuWidgetBase.hpp index 696b8a921..beb673b3f 100644 --- a/include/TGUI/Widgets/MenuWidgetBase.hpp +++ b/include/TGUI/Widgets/MenuWidgetBase.hpp @@ -370,6 +370,11 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void leftMouseButtonNoLongerDown() override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @internal + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void rightMousePressed(Vector2f pos) override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @internal ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/MenuWidgetBase.cpp b/src/Widgets/MenuWidgetBase.cpp index fb573ecf5..17d8f96fa 100644 --- a/src/Widgets/MenuWidgetBase.cpp +++ b/src/Widgets/MenuWidgetBase.cpp @@ -1009,6 +1009,14 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void OpenMenuPlaceholder::rightMousePressed(Vector2f pos) + { + if (!m_menuWidget->isMouseOnOpenMenu(pos - getPosition())) + m_menuWidget->closeMenu(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void OpenMenuPlaceholder::mouseMoved(Vector2f pos) { bool mouseOnMenuWidget = false; From ba7e5275052853c97a55b4f3594a848c046e73f4 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 16 Feb 2025 11:08:22 +0100 Subject: [PATCH 44/87] Don't add a BUILD_SHARED_LIBS cache variable when building TGUI as a subproject --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f3cc9aa9..d9a880e27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,10 @@ if(TGUI_OS_ANDROID) else() # If TGUI_SHARED_LIBS is explicitly set then it overrules BUILD_SHARED_LIBS, otherwise honor the global setting if(NOT DEFINED TGUI_SHARED_LIBS) - if(NOT DEFINED BUILD_SHARED_LIBS) + # Only create a cache variable for BUILD_SHARED_LIBS when TGUI is the top level project (or when CMake is too old to recognise it). + # The cache entry is made to help people who build TGUI with the CMake GUI. Creating such a cache variable in a subproject could + # lead to different behavior in the main project between first and subsequent CMake runs. + if(NOT DEFINED BUILD_SHARED_LIBS AND (CMAKE_VERSION VERSION_LESS 3.21 OR PROJECT_IS_TOP_LEVEL)) option(BUILD_SHARED_LIBS "ON to build a shared (dynamic) library, OFF to build a static library" ON) endif() From ac4a9c8b66985b68680f59f3e0ed2e0ea5c1dcb0 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 23 Feb 2025 10:49:22 +0100 Subject: [PATCH 45/87] Pass Vector2f by value in ToolTip::setDistanceToMouse --- include/TGUI/ToolTip.hpp | 2 +- src/ToolTip.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/TGUI/ToolTip.hpp b/include/TGUI/ToolTip.hpp index 09d3e51d5..8ab6425c5 100644 --- a/include/TGUI/ToolTip.hpp +++ b/include/TGUI/ToolTip.hpp @@ -59,7 +59,7 @@ TGUI_MODULE_EXPORT namespace tgui /// /// @param distance Distance between mouse and tool tip ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - static void setDistanceToMouse(const Vector2f& distance); + static void setDistanceToMouse(Vector2f distance); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns the default distance between the mouse position and the tool tip diff --git a/src/ToolTip.cpp b/src/ToolTip.cpp index 11db8fcc3..fb9a802fa 100644 --- a/src/ToolTip.cpp +++ b/src/ToolTip.cpp @@ -50,7 +50,7 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void ToolTip::setDistanceToMouse(const Vector2f& distance) + void ToolTip::setDistanceToMouse(Vector2f distance) { m_distanceToMouse = distance; } From a34f4cf81ee91e944d4e8b94da78fff156c7b173 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 23 Feb 2025 10:50:55 +0100 Subject: [PATCH 46/87] Updated version to 1.8 --- CMakeLists.txt | 2 +- changelog.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9a880e27..4a39bcb92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Macros.cmake) tgui_set_option(CMAKE_BUILD_TYPE Release STRING "Choose the type of build (Debug or Release)") # Project name and version -project(TGUI VERSION 1.7.0 LANGUAGES CXX) +project(TGUI VERSION 1.8.0 LANGUAGES CXX) # Use the paths from the cmake GNUInstallDirs module as defaults (https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) include(GNUInstallDirs) diff --git a/changelog.md b/changelog.md index f59a554be..1b5f72aab 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,5 @@ -TGUI 1.8 (TBD) ---------------- +TGUI 1.8 (23 February 2025) +---------------------------- - New widget: ContextMenu - Added handleWindowEvents function to SFML backend (only for SFML 3) From ec827035b21b39dfe3d2ce55dde377cfd38156a7 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 23 Feb 2025 22:21:36 +0100 Subject: [PATCH 47/87] Some fixes in how the documentation looks online --- doc/custom.css | 33 +++++++++++++++++++++++++++++++++ doc/doxyfile.in | 2 +- doc/header.html | 42 ++---------------------------------------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/doc/custom.css b/doc/custom.css index 9c4185afa..8d9a6f74f 100644 --- a/doc/custom.css +++ b/doc/custom.css @@ -8,3 +8,36 @@ color: #2a4d99; } } + +html { + --content-maxwidth: auto; +} + +body { + max-width: 100%; +} + +#body { + background-color: var(--page-background-color); +} + +div { + margin-bottom: 0 +} + +#contents { + padding-left: 0; + padding-right: 0; + padding-bottom: 0; + margin-left: 0; + margin-right: 0; + max-width: 100%; +} + +#doc-content { + height: auto !important; +} + +address.footer { + padding-bottom: 1.4em; +} diff --git a/doc/doxyfile.in b/doc/doxyfile.in index 5e69601fe..86be483e7 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -14,7 +14,7 @@ GENERATE_TESTLIST = NO GENERATE_BUGLIST = NO GENERATE_DEPRECATEDLIST= YES -GENERATE_TREEVIEW = YES +GENERATE_TREEVIEW = NO DISABLE_INDEX = NO FULL_SIDEBAR = NO HTML_COLORSTYLE = LIGHT diff --git a/doc/header.html b/doc/header.html index a946a1297..3ab31a6fe 100644 --- a/doc/header.html +++ b/doc/header.html @@ -1,7 +1,7 @@ --- --- - + @@ -29,50 +29,12 @@ $mathjax $darkmode -$extrastylesheet - - +$extrastylesheet From f41927d47f53740962ab1ba7df89526ba5b9c2b7 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 5 Mar 2025 22:50:07 +0100 Subject: [PATCH 48/87] Fixed multiple issues when using showWithEffect or hideWithEffect with a Fade type while another fade animation wasn't finished yet --- changelog.md | 6 ++++++ src/Widget.cpp | 16 ++++++++++++++- tests/Animation.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 1b5f72aab..0a19cae6f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +TGUI 1.9 (TBD) +--------------- + +- Fixed behavior of using showWithEffect or hideWithEffect with a Fade type while another fade animation wasn't finished yet + + TGUI 1.8 (23 February 2025) ---------------------------- diff --git a/src/Widget.cpp b/src/Widget.cpp index b7f0ac413..1e74b73a2 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -767,7 +767,10 @@ namespace tgui animStartOpacity = 0; } else // If fading was already in progress then adapt the duration to finish the animation sooner - duration *= (startOpacity / endOpacity); + { + duration *= (endOpacity - startOpacity) / endOpacity; + setInheritedOpacity(startOpacity); + } m_showAnimations.push_back(std::make_unique(shared_from_this(), animStartOpacity, endOpacity, duration, TGUI_LAMBDA_CAPTURE_EQ_THIS{ @@ -862,11 +865,19 @@ namespace tgui // use the current state to start our animation at, but this is not the state that the widget should end at. We must // get this state BEFORE finishing the previous animation which is done by finishExistingConflictingAnimations. const float startOpacity = getInheritedOpacity(); + const bool startVisibility = m_visible; //const Vector2f startPosition = getPosition(); //const Vector2f startSize = getSize(); finishExistingConflictingAnimations(m_showAnimations, type); + // If there already was a hide animation and the widget was still visible, + // then finishing the conflicting animation would hide the widget. + // We however only want to hide the widget after the new animation finishes, + // so we have to show the widget again for now. + if (startVisibility && !m_visible) + setVisible(true); + const Vector2f position = getPosition(); const Layout2d positionLayout = m_position; @@ -878,7 +889,10 @@ namespace tgui // If fading was already in progress then adapt the duration to finish the animation sooner if (startOpacity != endOpacity) + { duration *= (startOpacity / endOpacity); + setInheritedOpacity(startOpacity); + } m_showAnimations.push_back(std::make_unique(shared_from_this(), startOpacity, 0.f, duration, TGUI_LAMBDA_CAPTURE_EQ_THIS{ diff --git a/tests/Animation.cpp b/tests/Animation.cpp index 4fa7d8eca..2b445a9a6 100644 --- a/tests/Animation.cpp +++ b/tests/Animation.cpp @@ -84,7 +84,20 @@ TEST_CASE("[Animation]") widget->updateTime(std::chrono::milliseconds(100)); REQUIRE(widget->getInheritedOpacity() == Approx(0.3f)); widget->updateTime(std::chrono::milliseconds(200)); - REQUIRE(widget->getInheritedOpacity() == 0.9f); + REQUIRE(widget->getInheritedOpacity() == Approx(0.9f)); + + SECTION("continuing existing animation") + { + widget->showWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(1000)); + widget->updateTime(std::chrono::milliseconds(600)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.54f)); + + // It would take 2000ms to change opacity from 0% to 90%, + // but we are already at 54% so there is only 800ms left to go to 90% + widget->showWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(2000)); + widget->updateTime(std::chrono::milliseconds(700)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.855f)); + } } SECTION("Scale") @@ -144,7 +157,7 @@ TEST_CASE("[Animation]") widget->updateTime(std::chrono::milliseconds(100)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); REQUIRE(widget->getSize() == tgui::Vector2f(120, 30)); - REQUIRE(widget->getInheritedOpacity() == 0.9f); + REQUIRE(widget->getInheritedOpacity() == Approx(0.9f)); } SECTION("hideWithEffect") @@ -152,9 +165,20 @@ TEST_CASE("[Animation]") SECTION("Fade") { widget->hideWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(300)); - REQUIRE(widget->getInheritedOpacity() == 0.9f); + REQUIRE(widget->getInheritedOpacity() == Approx(0.9f)); widget->updateTime(std::chrono::milliseconds(100)); REQUIRE(widget->getInheritedOpacity() == Approx(0.6f)); + + SECTION("continuing existing animation") + { + widget->hideWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(1800)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.6f)); + + // It would take 1800ms to change opacity from 90% to 0%, + // but we are already at 60% so there is only 1200ms left to go to 0% + widget->updateTime(std::chrono::milliseconds(1000)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.1f)); + } } SECTION("Scale") @@ -215,6 +239,23 @@ TEST_CASE("[Animation]") REQUIRE(!widget->isVisible()); } + SECTION("showWithEffect + hideWithEffect") + { + widget->showWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(300)); + widget->updateTime(std::chrono::milliseconds(200)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.6f)); + + widget->hideWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(600)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.6f)); + widget->updateTime(std::chrono::milliseconds(300)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.15f)); + + widget->showWithEffect(tgui::ShowEffectType::Fade, std::chrono::milliseconds(400)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.15f)); + widget->updateTime(std::chrono::milliseconds(100)); + REQUIRE(widget->getInheritedOpacity() == Approx(0.375f)); + } + SECTION("moveWithAnimation") { widget->moveWithAnimation({230, 25}, 300); From 8998e8a0007921e002add6fb52e6aaba4a3ed4a6 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 5 Mar 2025 22:53:41 +0100 Subject: [PATCH 49/87] Also test released SFML 3 and SDL 3 versions in CI instead of only testing older versions and latest git version --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f01ace49..5f01b30c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -552,9 +552,9 @@ jobs: windows: # Setup technically not allowed, backends have conflicting FreeType dependencies runs-on: windows-2022 env: - SFML_VERSION: 2.6.0 - SDL_VERSION: 2.28.3 - SDL_TTF_VERSION: 2.20.2 + SFML_VERSION: 3.0.0 + SDL_VERSION: 3.2.6 + SDL_TTF_VERSION: 3.2.0 GLFW_VERSION: '3.4' RAYLIB_VERSION: '5.0' FREETYPE_VERSION: 2.13.2 @@ -566,14 +566,14 @@ jobs: - name: Install dependencies run: | C:\msys64\usr\bin\wget.exe -nv https://github.com/SFML/SFML/releases/download/${env:SFML_VERSION}/SFML-${env:SFML_VERSION}-windows-vc17-32-bit.zip - C:\msys64\usr\bin\wget.exe -nv https://github.com/libsdl-org/SDL/releases/download/release-${env:SDL_VERSION}/SDL2-devel-${env:SDL_VERSION}-VC.zip - C:\msys64\usr\bin\wget.exe -nv https://github.com/libsdl-org/SDL_ttf/releases/download/release-${env:SDL_TTF_VERSION}/SDL2_ttf-devel-${env:SDL_TTF_VERSION}-VC.zip + C:\msys64\usr\bin\wget.exe -nv https://github.com/libsdl-org/SDL/releases/download/release-${env:SDL_VERSION}/SDL3-devel-${env:SDL_VERSION}-VC.zip + C:\msys64\usr\bin\wget.exe -nv https://github.com/libsdl-org/SDL_ttf/releases/download/release-${env:SDL_TTF_VERSION}/SDL3_ttf-devel-${env:SDL_TTF_VERSION}-VC.zip C:\msys64\usr\bin\wget.exe -nv https://github.com/glfw/glfw/releases/download/${env:GLFW_VERSION}/glfw-${env:GLFW_VERSION}.bin.WIN32.zip C:\msys64\usr\bin\wget.exe -nv https://github.com/raysan5/raylib/releases/download/${env:RAYLIB_VERSION}/raylib-${env:RAYLIB_VERSION}_win32_msvc16.zip C:\msys64\usr\bin\wget.exe -nv https://github.com/ubawurinna/freetype-windows-binaries/archive/refs/tags/v${env:FREETYPE_VERSION}.zip 7z x SFML-${env:SFML_VERSION}-windows-vc17-32-bit.zip - 7z x SDL2-devel-${env:SDL_VERSION}-VC.zip - 7z x SDL2_ttf-devel-${env:SDL_TTF_VERSION}-VC.zip + 7z x SDL3-devel-${env:SDL_VERSION}-VC.zip + 7z x SDL3_ttf-devel-${env:SDL_TTF_VERSION}-VC.zip 7z x glfw-${env:GLFW_VERSION}.bin.WIN32.zip 7z x raylib-${env:RAYLIB_VERSION}_win32_msvc16.zip 7z x v${env:FREETYPE_VERSION}.zip @@ -582,8 +582,8 @@ jobs: run: > cmake -B TGUI-build -T v${env:MSVC_TOOLSET_VERSION} -A Win32 -DSFML_ROOT="${env:GITHUB_WORKSPACE}/SFML-${env:SFML_VERSION}/" - -DSDL2_DIR="${env:GITHUB_WORKSPACE}/SDL2-${env:SDL_VERSION}/cmake/" - -DSDL2_ttf_DIR="${env:GITHUB_WORKSPACE}/SDL2_ttf-${env:SDL_TTF_VERSION}/cmake/" + -DSDL3_DIR="${env:GITHUB_WORKSPACE}/SDL3-${env:SDL_VERSION}/cmake/" + -DSDL3_ttf_DIR="${env:GITHUB_WORKSPACE}/SDL3_ttf-${env:SDL_TTF_VERSION}/cmake/" -DGLFW_INCLUDE_DIR="${env:GITHUB_WORKSPACE}/glfw-${env:GLFW_VERSION}.bin.WIN32/include" -DGLFW_LIBRARY="${env:GITHUB_WORKSPACE}/glfw-${env:GLFW_VERSION}.bin.WIN32/lib-vc2022/glfw3dll.lib" -Draylib_INCLUDE_DIR="${env:GITHUB_WORKSPACE}/raylib-${env:RAYLIB_VERSION}_win32_msvc16/include" From d60dca092b7ab1277ec439921494d2e6cc95ee76 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 19:31:31 +0100 Subject: [PATCH 50/87] Ignore -Wcast-function-type-mismatch from Clang 19 when casting result of GetProcAddress --- src/FileDialogIconLoaderWindows.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/FileDialogIconLoaderWindows.cpp b/src/FileDialogIconLoaderWindows.cpp index 0bb6f42e1..2cdeeb3e1 100644 --- a/src/FileDialogIconLoaderWindows.cpp +++ b/src/FileDialogIconLoaderWindows.cpp @@ -136,13 +136,20 @@ namespace tgui m_dllModuleHandle = LoadLibraryW(L"shell32.dll"); if (m_dllModuleHandle) { -#if defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-function-type" +#if defined(__clang__) +# pragma clang diagnostic push +# if defined(__clang_major__) && (__clang_major__ >= 19) +# pragma clang diagnostic ignored "-Wcast-function-type-mismatch" +# endif +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" #endif m_dllGetFileInfoFuncHandle = reinterpret_cast(GetProcAddress(m_dllModuleHandle, "SHGetFileInfoW")); -#if defined(__GNUC__) - #pragma GCC diagnostic pop +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop #endif } From 888aa1992ae0bbb8c9371c9304a14bde1db3ea84 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 19:31:59 +0100 Subject: [PATCH 51/87] SDL_SetClipboardText returns a bool in SDL3 --- src/Backend/Window/SDL/BackendSDL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Backend/Window/SDL/BackendSDL.cpp b/src/Backend/Window/SDL/BackendSDL.cpp index dd410c8ed..dba50bffe 100644 --- a/src/Backend/Window/SDL/BackendSDL.cpp +++ b/src/Backend/Window/SDL/BackendSDL.cpp @@ -259,7 +259,11 @@ namespace tgui { #ifdef TGUI_SYSTEM_WINDOWS // If setting the clipboard fails on Windows then sleep a moment and try again +#if SDL_MAJOR_VERSION >= 3 + if (!SDL_SetClipboardText(contents.toStdString().c_str())) +#else if (SDL_SetClipboardText(contents.toStdString().c_str()) < 0) +#endif { Sleep(1); SDL_SetClipboardText(contents.toStdString().c_str()); From 507b2ee848340acd8551ef3183db451925efc03c Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 19:34:01 +0100 Subject: [PATCH 52/87] Be explicit about the value of raylib_USE_STATIC_LIBS in CMake everywhere, as the default value changed in raylib 5.6-dev --- .github/workflows/ci.yml | 10 ++++++++++ cmake/Dependencies.cmake | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f01b30c3..3b60250e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,7 @@ jobs: -DTGUI_HAS_BACKEND_GLFW_OPENGL3=ON -DTGUI_HAS_BACKEND_GLFW_GLES2=ON -DTGUI_HAS_BACKEND_RAYLIB=ON + -Draylib_USE_STATIC_LIBS=OFF cmake --build TGUI-build-gcc --config Debug --target install @@ -67,6 +68,7 @@ jobs: -DTGUI_HAS_BACKEND_GLFW_OPENGL3=ON -DTGUI_HAS_BACKEND_GLFW_GLES2=ON -DTGUI_HAS_BACKEND_RAYLIB=ON + -Draylib_USE_STATIC_LIBS=OFF cmake --build TGUI-build-clang --config Release @@ -189,6 +191,7 @@ jobs: -DSDL3_ttf_DIR="$GITHUB_WORKSPACE/SDL_TTF_INSTALL/lib/cmake/SDL3_ttf/" -Dglfw3_DIR="$GITHUB_WORKSPACE/GLFW_INSTALL/lib/cmake/glfw3/" -Draylib_ROOT="$GITHUB_WORKSPACE/RAYLIB_INSTALL/" + -Draylib_USE_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug -DTGUI_CXX_STANDARD=20 @@ -236,6 +239,7 @@ jobs: -DSDL3_ttf_DIR="$GITHUB_WORKSPACE/SDL_TTF_INSTALL/lib/cmake/SDL3_ttf/" -Dglfw3_DIR="$GITHUB_WORKSPACE/GLFW_INSTALL/lib/cmake/glfw3/" -Draylib_ROOT="$GITHUB_WORKSPACE/RAYLIB_INSTALL/" + -Draylib_USE_STATIC_LIBS=OFF cmake --build tests/cmake/build --config Release @@ -362,6 +366,7 @@ jobs: -DSDL2_TTF_PATH="$GITHUB_WORKSPACE/SDL_TTF_INSTALL" -Dglfw3_DIR="$GITHUB_WORKSPACE/GLFW_INSTALL/lib/cmake/glfw3/" -Draylib_ROOT="$GITHUB_WORKSPACE/RAYLIB_INSTALL/" + -Draylib_USE_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -DTGUI_CXX_STANDARD=14 -DTGUI_WARNINGS_AS_ERRORS=ON @@ -391,6 +396,7 @@ jobs: -DSDL2_TTF_PATH="$GITHUB_WORKSPACE/SDL_TTF_INSTALL" -Dglfw3_DIR="$GITHUB_WORKSPACE/GLFW_INSTALL/lib/cmake/glfw3/" -Draylib_ROOT="$GITHUB_WORKSPACE/RAYLIB_INSTALL/" + -Draylib_USE_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -DTGUI_CXX_STANDARD=14 -DTGUI_WARNINGS_AS_ERRORS=ON @@ -419,6 +425,7 @@ jobs: -DSDL2_TTF_PATH="$GITHUB_WORKSPACE/SDL_TTF_INSTALL" -Dglfw3_DIR="$GITHUB_WORKSPACE/GLFW_INSTALL/lib/cmake/glfw3/" -Draylib_ROOT="$GITHUB_WORKSPACE/RAYLIB_INSTALL/" + -Draylib_USE_STATIC_LIBS=OFF cmake --build tests/cmake/build --config Debug @@ -540,6 +547,7 @@ jobs: -DTGUI_BUILD_TESTS=OFF -DCMAKE_UNITY_BUILD=ON -DTGUI_BACKEND=RAYLIB + -Draylib_USE_STATIC_LIBS=OFF sudo cmake --build TGUI-build-RAYLIB --config Debug --target install @@ -856,6 +864,7 @@ jobs: -DTGUI_HAS_BACKEND_SDL_TTF_OPENGL3=ON -DTGUI_HAS_BACKEND_GLFW_OPENGL3=ON -DTGUI_HAS_BACKEND_RAYLIB=ON + -Draylib_USE_STATIC_LIBS=OFF cmake --build TGUI-build-dylibs --config Debug --target install @@ -883,6 +892,7 @@ jobs: -DTGUI_HAS_BACKEND_SDL_TTF_OPENGL3=ON -DTGUI_HAS_BACKEND_GLFW_OPENGL3=ON -DTGUI_HAS_BACKEND_RAYLIB=ON + -Draylib_USE_STATIC_LIBS=OFF cmake --build TGUI-build-framework --config Release --target install diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 9d3aeca66..9f16b59c1 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -609,6 +609,14 @@ endfunction() # Find raylib and add it as a dependency macro(tgui_add_dependency_raylib) if(NOT TARGET raylib) + # If raylib_INCLUDE_DIR and raylib_LIBRARY were previously created as CACHE variables by the Findraylib.cmake file, + # then they might interfere with the code in raylib-config.cmake when it is found (e.g. user filled in raylib_DIR). + # So we remove these variables when they are empty (they will be set again by either the config file or find module). + if (NOT raylib_INCLUDE_DIR AND NOT raylib_LIBRARY) + unset(raylib_INCLUDE_DIR CACHE) + unset(raylib_LIBRARY CACHE) + endif() + # First try looking for an raylib config file tgui_try_find_raylib_config() @@ -620,7 +628,7 @@ macro(tgui_add_dependency_raylib) if(NOT raylib_FOUND) message(FATAL_ERROR "CMake couldn't find raylib.\n" - "If raylib was build with CMake then set the raylib_DIR variable to the directory containing raylib-config.cmake (i.e. RAYLIB_ROOT/lib/cmake/raylib)\n" + "If raylib was build with CMake then set the raylib_DIR variable to the directory containing raylib-config.cmake (i.e. RAYLIB_ROOT/lib/cmake/raylib). Also check that the value of raylib_USE_STATIC_LIBS is correct.\n" "Alternatively you can manually set raylib_INCLUDE_DIR to the 'include' directory and raylib_LIBRARY to the correct library file. You are responsible for making sure the selected library is compatible.\n") endif() From 975d99c8db88a7d6235e87498f3966b49b41d7ff Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 19:43:33 +0100 Subject: [PATCH 53/87] Ignore -Wcast-function-type-mismatch from Clang 19 when casting result of GetProcAddress in another place as well --- src/WindowsIMM.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/WindowsIMM.cpp b/src/WindowsIMM.cpp index 588a52bac..d2abe4b55 100644 --- a/src/WindowsIMM.cpp +++ b/src/WindowsIMM.cpp @@ -54,15 +54,22 @@ namespace tgui m_dllImmModuleHandle = LoadLibraryW(L"imm32.dll"); if (m_dllImmModuleHandle) { -#if defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-function-type" +#if defined(__clang__) +# pragma clang diagnostic push +# if defined(__clang_major__) && (__clang_major__ >= 19) +# pragma clang diagnostic ignored "-Wcast-function-type-mismatch" +# endif +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" #endif m_dllImmGetContext = reinterpret_cast(GetProcAddress(m_dllImmModuleHandle, "ImmGetContext")); m_dllImmSetCompositionWindow = reinterpret_cast(GetProcAddress(m_dllImmModuleHandle, "ImmSetCompositionWindow")); m_dllImmReleaseContext = reinterpret_cast(GetProcAddress(m_dllImmModuleHandle, "ImmReleaseContext")); -#if defined(__GNUC__) - #pragma GCC diagnostic pop +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop #endif } } From df1c903364f090770990406d8ca81c3bdd490956 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 19:45:06 +0100 Subject: [PATCH 54/87] ptsize is a float in TTF_OpenFontIO in SDL3_ttf --- src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp index 48ef74a93..4d8ea5b15 100644 --- a/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp +++ b/src/Backend/Font/SDL_ttf/BackendFontSDLttf.cpp @@ -368,7 +368,7 @@ namespace tgui if (!handle) return nullptr; - auto font = TTF_OpenFontIO(handle, true, static_cast(scaledTextSize)); + auto font = TTF_OpenFontIO(handle, true, static_cast(scaledTextSize)); #else SDL_RWops* handle = SDL_RWFromConstMem(m_fileContents.get(), static_cast(m_fileSize)); if (!handle) From 3d1e5ca98e1b5396e08207c3a6ce5534819eb212 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Thu, 6 Mar 2025 23:12:01 +0100 Subject: [PATCH 55/87] Run ubuntu 20.04 tests in docker container because Github will stop supporting this runner image version --- .github/workflows/ci.yml | 33 +++++++++++++++++++++------------ tests/cmake/CMakeLists.txt | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b60250e6..16d1d4182 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: #---------------------------------------- linux-latest-dev: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: SFML_GITHUB_URL: https://github.com/SFML/SFML SDL_GITHUB_URL: https://github.com/libsdl-org/SDL @@ -260,7 +260,7 @@ jobs: #---------------------------------------- linux-oldest: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: SFML_VERSION: 2.5.1 # 2.5.0 has issue with mesa SDL_VERSION: 2.0.18 # older versions aren't supported in SDL_RENDERER backend @@ -271,6 +271,13 @@ jobs: CMAKE_VERSION_PATCH: 0 GCC_VERSION: 7 CLANG_VERSION: '6.0' + + container: + image: ubuntu:20.04 + env: + DEBIAN_FRONTEND: noninteractive + TZ: Etc/UTC + steps: - name: Checkout TGUI uses: actions/checkout@v4 @@ -312,17 +319,17 @@ jobs: - name: Install build tools and dependencies run: | - sudo apt-get update - sudo apt-get -y install g++-$GCC_VERSION clang-$CLANG_VERSION ninja-build - sudo apt-get -y install xorg-dev libudev-dev libopenal-dev libflac-dev libvorbis-dev libgl1-mesa-dev libegl1-mesa-dev libfreetype6-dev - sudo sh -c 'wget -nv -O- "https://cmake.org/files/v${{env.CMAKE_VERSION}}/cmake-${{env.CMAKE_VERSION}}.${{env.CMAKE_VERSION_PATCH}}-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local' + apt-get update + apt-get -y install g++-$GCC_VERSION clang-$CLANG_VERSION ninja-build wget + apt-get -y install xorg-dev libudev-dev libopenal-dev libflac-dev libvorbis-dev libgl1-mesa-dev libegl1-mesa-dev libfreetype6-dev + sh -c 'wget -nv -O- "https://cmake.org/files/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.${CMAKE_VERSION_PATCH}-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local' - name: Build SFML if: steps.cache-sfml.outputs.cache-hit != 'true' run: | mkdir SFML wget -nv -O- "https://github.com/SFML/SFML/archive/refs/tags/$SFML_VERSION.tar.gz" | tar --strip-components=1 -xz -C SFML - cmake -GNinja -DCMAKE_INSTALL_PREFIX=SFML_INSTALL -DBUILD_SHARED_LIBS=ON -DSFML_BUILD_AUDIO=OFF -DSFML_BUILD_NETWORK=OFF -S SFML -B SFML-build + cmake -GNinja -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_INSTALL_PREFIX=SFML_INSTALL -DBUILD_SHARED_LIBS=ON -DSFML_BUILD_AUDIO=OFF -DSFML_BUILD_NETWORK=OFF -S SFML -B SFML-build cmake --build SFML-build --config Release --target install - name: Build SDL @@ -330,7 +337,7 @@ jobs: run: | mkdir SDL wget -nv -O- "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$SDL_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL - cmake -GNinja -DCMAKE_INSTALL_PREFIX=SDL_INSTALL -DBUILD_SHARED_LIBS=ON -S SDL -B SDL-build + cmake -GNinja -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_INSTALL_PREFIX=SDL_INSTALL -DBUILD_SHARED_LIBS=ON -S SDL -B SDL-build cmake --build SDL-build --config Release --target install - name: Build SDL_ttf @@ -338,7 +345,7 @@ jobs: run: | mkdir SDL_TTF wget -nv -O- "https://github.com/libsdl-org/SDL_ttf/archive/refs/tags/release-$SDL_TTF_VERSION.tar.gz" | tar --strip-components=1 -xz -C SDL_TTF - cmake -GNinja -DCMAKE_INSTALL_PREFIX=SDL_TTF_INSTALL -DSDL2_DIR="$GITHUB_WORKSPACE/SDL_INSTALL/lib/cmake/SDL2" -DBUILD_SHARED_LIBS=ON -S SDL_TTF -B SDL_TTF-build + cmake -GNinja -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_INSTALL_PREFIX=SDL_TTF_INSTALL -DSDL2_DIR="$GITHUB_WORKSPACE/SDL_INSTALL/lib/cmake/SDL2" -DBUILD_SHARED_LIBS=ON -S SDL_TTF -B SDL_TTF-build cmake --build SDL_TTF-build --config Release --target install - name: Build GLFW @@ -346,7 +353,7 @@ jobs: run: | mkdir GLFW wget -nv -O- "https://github.com/glfw/glfw/archive/refs/tags/$GLFW_VERSION.tar.gz" | tar --strip-components=1 -xz -C GLFW - cmake -GNinja -DCMAKE_INSTALL_PREFIX=GLFW_INSTALL -DBUILD_SHARED_LIBS=ON -S GLFW -B GLFW-build + cmake -GNinja -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_INSTALL_PREFIX=GLFW_INSTALL -DBUILD_SHARED_LIBS=ON -S GLFW -B GLFW-build cmake --build GLFW-build --config Release --target install - name: Build raylib @@ -354,7 +361,7 @@ jobs: run: | mkdir raylib wget -nv -O- "https://github.com/raysan5/raylib/archive/refs/tags/$RAYLIB_VERSION.tar.gz" | tar --strip-components=1 -xz -C raylib - cmake -GNinja -DCMAKE_INSTALL_PREFIX=RAYLIB_INSTALL -DBUILD_SHARED_LIBS=ON -S raylib -B raylib-build + cmake -GNinja -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_INSTALL_PREFIX=RAYLIB_INSTALL -DBUILD_SHARED_LIBS=ON -S raylib -B raylib-build cmake --build raylib-build --config Release --target install - name: Build TGUI (old gcc) @@ -415,11 +422,13 @@ jobs: -DTGUI_HAS_BACKEND_GLFW_GLES2=ON -DTGUI_HAS_BACKEND_RAYLIB=ON - sudo cmake --build TGUI-build-clang --config Debug --target install + cmake --build TGUI-build-clang --config Debug --target install - name: Test TGUIConfig.cmake run: > cmake -GNinja -S tests/cmake -B tests/cmake/build + -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION + -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DSFML_DIR="$GITHUB_WORKSPACE/SFML_INSTALL/lib/cmake/SFML/" -DSDL2_DIR="$GITHUB_WORKSPACE/SDL_INSTALL/lib/cmake/SDL2/" -DSDL2_TTF_PATH="$GITHUB_WORKSPACE/SDL_TTF_INSTALL" diff --git a/tests/cmake/CMakeLists.txt b/tests/cmake/CMakeLists.txt index 7e0ec7912..2251a307d 100644 --- a/tests/cmake/CMakeLists.txt +++ b/tests/cmake/CMakeLists.txt @@ -6,6 +6,6 @@ add_executable(TguiTest main.cpp) find_package(TGUI 1 REQUIRED) target_link_libraries(TguiTest PRIVATE TGUI::TGUI) -set_target_properties(TguiTest PROPERTIES CXX_STANDARD 20) +set_target_properties(TguiTest PROPERTIES CXX_STANDARD 17) set_target_properties(TguiTest PROPERTIES CXX_STANDARD_REQUIRED ON) set_target_properties(TguiTest PROPERTIES CXX_EXTENSIONS OFF) From a29e7935c4ea64bc34624060f0568ea5ff41a373 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Fri, 7 Mar 2025 22:06:12 +0100 Subject: [PATCH 56/87] Skip gui.handleWindowEvents test until SFML/SFML#3454 is fixed --- tests/BackendEvents.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/BackendEvents.cpp b/tests/BackendEvents.cpp index c295a5a58..da34aef94 100644 --- a/tests/BackendEvents.cpp +++ b/tests/BackendEvents.cpp @@ -80,6 +80,8 @@ TEST_CASE("[Backend events]") SECTION("SFML") { #if SFML_VERSION_MAJOR >= 3 + // This test is temporarily disabled on Windows because of an issue in SFML (https://github.com/SFML/SFML/issues/3454) + #ifndef TGUI_SYSTEM_WINDOWS SECTION("handleWindowEvents") { // We can't test whether the functions get called correctly (as that would require @@ -92,6 +94,7 @@ TEST_CASE("[Backend events]") [](auto&&) {} ); } + #endif #endif SECTION("KeyPressed") From a1d5be795864404635f3126d1e453477f9e17141 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Fri, 7 Mar 2025 22:38:48 +0100 Subject: [PATCH 57/87] TGUIConfig.cmake test was still searching for SDL2 in test where only SDL3 was installed --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16d1d4182..aaf13fbdc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -627,8 +627,8 @@ jobs: cmake -T v${env:MSVC_TOOLSET_VERSION} -A Win32 -S tests/cmake -B tests/cmake/build -DTGUI_ROOT="${env:GITHUB_WORKSPACE}/TGUI-build/install" -DSFML_ROOT="${env:GITHUB_WORKSPACE}/SFML-${env:SFML_VERSION}" - -DSDL2_DIR="${env:GITHUB_WORKSPACE}/SDL2-${env:SDL_VERSION}/cmake/" - -DSDL2_ttf_DIR="${env:GITHUB_WORKSPACE}/SDL2_ttf-${env:SDL_TTF_VERSION}/cmake/" + -DSDL3_DIR="${env:GITHUB_WORKSPACE}/SDL3-${env:SDL_VERSION}/cmake/" + -DSDL3_ttf_DIR="${env:GITHUB_WORKSPACE}/SDL3_ttf-${env:SDL_TTF_VERSION}/cmake/" -DGLFW_INCLUDE_DIR="${env:GITHUB_WORKSPACE}/glfw-${env:GLFW_VERSION}.bin.WIN32/include" -DGLFW_LIBRARY="${env:GITHUB_WORKSPACE}/glfw-${env:GLFW_VERSION}.bin.WIN32/lib-vc2022/glfw3dll.lib" -Draylib_INCLUDE_DIR="${env:GITHUB_WORKSPACE}/raylib-${env:RAYLIB_VERSION}_win32_msvc16/include" From d5ecdeb3c0a3dc60bd57b49b6995e7d70f99fdf5 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sat, 8 Mar 2025 17:10:11 +0100 Subject: [PATCH 58/87] Increase usable range in SpinButton and SpinControl by internally using doubles (#254) --- include/TGUI/Widgets/SpinButton.hpp | 37 +++++++++++++++++++---- include/TGUI/Widgets/SpinControl.hpp | 22 ++++++++++++-- src/Widgets/SpinButton.cpp | 44 +++++----------------------- src/Widgets/SpinControl.cpp | 20 ------------- 4 files changed, 59 insertions(+), 64 deletions(-) diff --git a/include/TGUI/Widgets/SpinButton.hpp b/include/TGUI/Widgets/SpinButton.hpp index 37e22e30b..cc43b7e88 100644 --- a/include/TGUI/Widgets/SpinButton.hpp +++ b/include/TGUI/Widgets/SpinButton.hpp @@ -144,7 +144,26 @@ TGUI_MODULE_EXPORT namespace tgui /// The value can't be smaller than the minimum or bigger than the maximum. /// The default value is 0. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setValue(float value); + template ::value, T>> + void setValue(T value) + { + // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings. + // We however need the function to take a double as parameter to actually make use of the extra significant digits. + const double oldValue = m_value; + + // Round to nearest allowed value + if (m_step != 0) + m_value = m_minimum + (std::round((static_cast(value) - m_minimum) / m_step) * m_step); + + // When the value is below the minimum or above the maximum then adjust it + if (m_value < m_minimum) + m_value = m_minimum; + else if (m_value > m_maximum) + m_value = m_maximum; + + if (oldValue != m_value) + onValueChange.emit(this, static_cast(m_value)); + } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns the current value @@ -160,7 +179,13 @@ TGUI_MODULE_EXPORT namespace tgui /// @param step The new step size /// @pre The step size must be a positive value or 0. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setStep(float step); + template ::value, T>> + void setStep(T step) + { + // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings. + // We however need the function to take a double as parameter to actually make use of the extra significant digits in calculations. + m_step = static_cast(step); + } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns the number of positions the thumb advances with each move @@ -282,10 +307,10 @@ TGUI_MODULE_EXPORT namespace tgui bool m_orientationLocked = false; // Will setSize change the orientation or not? std::chrono::time_point m_PressedAt; - float m_minimum = 0; - float m_maximum = 10; - float m_value = 0; - float m_step = 1; + double m_minimum = 0; + double m_maximum = 10; + double m_value = 0; + double m_step = 1; // On which arrow is the mouse? bool m_mouseHoverOnTopArrow = false; diff --git a/include/TGUI/Widgets/SpinControl.hpp b/include/TGUI/Widgets/SpinControl.hpp index 5b6010666..062ebc38a 100644 --- a/include/TGUI/Widgets/SpinControl.hpp +++ b/include/TGUI/Widgets/SpinControl.hpp @@ -179,7 +179,19 @@ TGUI_MODULE_EXPORT namespace tgui /// The value can't be smaller than the minimum or bigger than the maximum. /// The default value is 0. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool setValue(float value); + template ::value, T>> + bool setValue(T value) + { + // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings. + // We however need the function to take a double as parameter to actually make use of the extra significant digits. + if (m_spinButton->getValue() != static_cast(value) && inRange(static_cast(value))) + { + m_spinButton->setValue(value); + setString(String::fromNumberRounded(value, m_decimalPlaces)); + return true; + } + return false; + } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns the current value @@ -195,7 +207,13 @@ TGUI_MODULE_EXPORT namespace tgui /// @param step The new step size /// @pre The step size must be a positive value or 0. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void setStep(float step); + template ::value, T>> + void setStep(T step) + { + // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings. + // We however need the function to take a double as parameter to actually make use of the extra significant digits in calculations. + m_spinButton->setStep(step); + } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Returns the number of positions the thumb advances with each move diff --git a/src/Widgets/SpinButton.cpp b/src/Widgets/SpinButton.cpp index 05086bd5b..f77db7c61 100644 --- a/src/Widgets/SpinButton.cpp +++ b/src/Widgets/SpinButton.cpp @@ -136,11 +136,11 @@ namespace tgui void SpinButton::setMinimum(float minimum) { // Set the new minimum - m_minimum = minimum; + m_minimum = static_cast(minimum); // The minimum can never be greater than the maximum if (m_minimum > m_maximum) - setMaximum(m_minimum); + setMaximum(getMinimum()); // When the value is below the minimum then adjust it if (m_value < m_minimum) @@ -151,18 +151,18 @@ namespace tgui float SpinButton::getMinimum() const { - return m_minimum; + return static_cast(m_minimum); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SpinButton::setMaximum(float maximum) { - m_maximum = maximum; + m_maximum = static_cast(maximum); // The maximum can never be below the minimum if (m_maximum < m_minimum) - setMinimum(m_maximum); + setMinimum(getMaximum()); // When the value is above the maximum then adjust it if (m_value > m_maximum) @@ -173,49 +173,21 @@ namespace tgui float SpinButton::getMaximum() const { - return m_maximum; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void SpinButton::setValue(float value) - { - // Round to nearest allowed value - if (m_step != 0) - value = m_minimum + (std::round((value - m_minimum) / m_step) * m_step); - - // When the value is below the minimum or above the maximum then adjust it - if (value < m_minimum) - value = m_minimum; - else if (value > m_maximum) - value = m_maximum; - - if (m_value != value) - { - m_value = value; - onValueChange.emit(this, value); - } + return static_cast(m_maximum); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float SpinButton::getValue() const { - return m_value; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - void SpinButton::setStep(float step) - { - m_step = step; + return static_cast(m_value); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float SpinButton::getStep() const { - return m_step; + return static_cast(m_step); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Widgets/SpinControl.cpp b/src/Widgets/SpinControl.cpp index 4ed3d820f..a26985925 100644 --- a/src/Widgets/SpinControl.cpp +++ b/src/Widgets/SpinControl.cpp @@ -233,19 +233,6 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool SpinControl::setValue(float value) - { - if (m_spinButton->getValue() != value && inRange(value)) - { - m_spinButton->setValue(value); - setString(String::fromNumberRounded(value, m_decimalPlaces)); - return true; - } - return false; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - float SpinControl::getValue() const { return m_spinButton->getValue(); @@ -253,13 +240,6 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void SpinControl::setStep(float step) - { - m_spinButton->setStep(step); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - float SpinControl::getStep() const { return m_spinButton->getStep(); From 8dbcaee8e3f139ab847a7cb500e9938ddf3a8c9d Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sat, 8 Mar 2025 17:28:30 +0100 Subject: [PATCH 59/87] cmath include needs to be moved to SpinButton header now that setValue implementation was moved there --- include/TGUI/Widgets/SpinButton.hpp | 4 ++++ src/Widgets/SpinButton.cpp | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/TGUI/Widgets/SpinButton.hpp b/include/TGUI/Widgets/SpinButton.hpp index cc43b7e88..4442d7a29 100644 --- a/include/TGUI/Widgets/SpinButton.hpp +++ b/include/TGUI/Widgets/SpinButton.hpp @@ -29,6 +29,10 @@ #include #include +#if !TGUI_EXPERIMENTAL_USE_STD_MODULE + #include +#endif + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_MODULE_EXPORT namespace tgui diff --git a/src/Widgets/SpinButton.cpp b/src/Widgets/SpinButton.cpp index f77db7c61..ac5c7f1ba 100644 --- a/src/Widgets/SpinButton.cpp +++ b/src/Widgets/SpinButton.cpp @@ -24,10 +24,6 @@ #include -#if !TGUI_EXPERIMENTAL_USE_STD_MODULE - #include -#endif - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace tgui From 642594bdecb83cfba1a6b304df4ee8ae7cf82b51 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 12 Mar 2025 19:39:52 +0100 Subject: [PATCH 60/87] Added mapPixelToCoords and mapCoordsToPixel to CanvasSFML --- changelog.md | 1 + .../Renderer/SFML-Graphics/CanvasSFML.hpp | 16 ++++++++++ .../Renderer/SFML-Graphics/CanvasSFML.cpp | 29 ++++++++++++++++++ tests/Animation.cpp | 30 ++++++++----------- tests/Layouts.cpp | 4 --- tests/Tests.cpp | 9 ++++++ tests/Tests.hpp | 1 + tests/Widgets/Canvas.cpp | 8 +++-- 8 files changed, 74 insertions(+), 24 deletions(-) diff --git a/changelog.md b/changelog.md index 0a19cae6f..066f6016c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ TGUI 1.9 (TBD) --------------- +- Added mapPixelToCoords and mapCoordsToPixel to CanvasSFML - Fixed behavior of using showWithEffect or hideWithEffect with a Fade type while another fade animation wasn't finished yet diff --git a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp index b28bc5b38..2251267f9 100644 --- a/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp +++ b/include/TGUI/Backend/Renderer/SFML-Graphics/CanvasSFML.hpp @@ -184,6 +184,22 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TGUI_NODISCARD IntRect getViewport() const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Converts a point on the canvas to a position within the canvas view + /// @param point coordinate of point on top of the canvas + /// @return The converted point, in "world" coordinates + /// @since TGUI 1.9 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f mapPixelToCoords(Vector2f point) const; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// @brief Converts a position within the canvas view to the corresponding point on the canvas + /// @param coord position within the canvas view + /// @return The converted point, relative to the canvas position + /// @since TGUI 1.9 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TGUI_NODISCARD Vector2f mapCoordsToPixel(Vector2f coord) const; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Enable or disable texture smoothing /// diff --git a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp index e1b1e0348..55d8ba3bd 100644 --- a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp @@ -188,6 +188,35 @@ namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Vector2f CanvasSFML::mapPixelToCoords(Vector2f point) const + { + const Vector2f size = getSize(); + const sf::View& view = m_renderTexture.getView(); + const sf::FloatRect& viewport = view.getViewport(); + + const sf::Vector2f normalized = { + -1 + (2 * (point.x - (viewport.position.x * size.x)) / (viewport.size.x * size.x)), + 1 + (-2 * (point.y - (viewport.position.y * size.y)) / (viewport.size.y * size.y)) + }; + const sf::Vector2f coord = view.getInverseTransform().transformPoint(normalized); + return {coord.x, coord.y}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + TGUI_NODISCARD Vector2f CanvasSFML::mapCoordsToPixel(Vector2f coord) const + { + const Vector2f size = getSize(); + const sf::View& view = m_renderTexture.getView(); + const sf::FloatRect& viewport = view.getViewport(); + + const sf::Vector2f normalized = view.getTransform().transformPoint(coord); + return {(normalized.x + 1) / 2 * (viewport.size.x * size.x) + (viewport.position.x * size.x), + (-normalized.y + 1) / 2 * (viewport.size.y * size.y) + (viewport.position.y * size.y)}; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void CanvasSFML::setSmooth(bool smooth) { m_renderTexture.setSmooth(smooth); diff --git a/tests/Animation.cpp b/tests/Animation.cpp index 2b445a9a6..8bf2d5cce 100644 --- a/tests/Animation.cpp +++ b/tests/Animation.cpp @@ -24,12 +24,6 @@ #include "Tests.hpp" -static void compareVector2f(tgui::Vector2f left, tgui::Vector2f right) -{ - REQUIRE(left.x == Approx(right.x).margin(0.000001f)); - REQUIRE(left.y == Approx(right.y).margin(0.000001f)); -} - TEST_CASE("[Animation]") { tgui::Widget::Ptr widget = tgui::ClickableWidget::create(); @@ -106,8 +100,8 @@ TEST_CASE("[Animation]") REQUIRE(widget->getPosition() == tgui::Vector2f(90, 30)); REQUIRE(widget->getSize() == tgui::Vector2f(0, 0)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {70, 25}); - compareVector2f(widget->getSize(), {40, 10}); + REQUIRE(compareVector2f(widget->getPosition(), {70, 25})); + REQUIRE(compareVector2f(widget->getSize(), {40, 10})); widget->updateTime(std::chrono::milliseconds(200)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); REQUIRE(widget->getSize() == tgui::Vector2f(120, 30)); @@ -118,7 +112,7 @@ TEST_CASE("[Animation]") widget->showWithEffect(tgui::ShowEffectType::SlideFromLeft, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(-120, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {-120.f+((120.f+30.f)/3.f), 15}); + REQUIRE(compareVector2f(widget->getPosition(), {-120.f+((120.f+30.f)/3.f), 15})); widget->updateTime(std::chrono::milliseconds(200)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); } @@ -128,7 +122,7 @@ TEST_CASE("[Animation]") widget->showWithEffect(tgui::ShowEffectType::SlideFromTop, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, -30)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30, -30.f+((30.f+15.f)/3.f)}); + REQUIRE(compareVector2f(widget->getPosition(), {30, -30.f+((30.f+15.f)/3.f)})); widget->updateTime(std::chrono::milliseconds(200)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); } @@ -138,7 +132,7 @@ TEST_CASE("[Animation]") widget->showWithEffect(tgui::ShowEffectType::SlideFromRight, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(480, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {480-((480-30)/3.f), 15}); + REQUIRE(compareVector2f(widget->getPosition(), {480-((480-30)/3.f), 15})); widget->updateTime(std::chrono::milliseconds(200)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); } @@ -148,7 +142,7 @@ TEST_CASE("[Animation]") widget->showWithEffect(tgui::ShowEffectType::SlideFromBottom, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 360)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30, 360-((360-15)/3.f)}); + REQUIRE(compareVector2f(widget->getPosition(), {30, 360-((360-15)/3.f)})); widget->updateTime(std::chrono::milliseconds(200)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); } @@ -187,8 +181,8 @@ TEST_CASE("[Animation]") REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); REQUIRE(widget->getSize() == tgui::Vector2f(120, 30)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {50, 20}); - compareVector2f(widget->getSize(), {80, 20}); + REQUIRE(compareVector2f(widget->getPosition(), {50, 20})); + REQUIRE(compareVector2f(widget->getSize(), {80, 20})); } SECTION("SlideToRight") @@ -196,7 +190,7 @@ TEST_CASE("[Animation]") widget->hideWithEffect(tgui::ShowEffectType::SlideToRight, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30+((480-30)/3.f), 15}); + REQUIRE(compareVector2f(widget->getPosition(), {30+((480-30)/3.f), 15})); } SECTION("SlideToBottom") @@ -204,7 +198,7 @@ TEST_CASE("[Animation]") widget->hideWithEffect(tgui::ShowEffectType::SlideToBottom, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30, 15+((360-15)/3.f)}); + REQUIRE(compareVector2f(widget->getPosition(), {30, 15+((360-15)/3.f)})); } SECTION("SlideToLeft") @@ -212,7 +206,7 @@ TEST_CASE("[Animation]") widget->hideWithEffect(tgui::ShowEffectType::SlideToLeft, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30.f-((120.f+30.f)/3.f), 15}); + REQUIRE(compareVector2f(widget->getPosition(), {30.f-((120.f+30.f)/3.f), 15})); } SECTION("SlideToTop") @@ -220,7 +214,7 @@ TEST_CASE("[Animation]") widget->hideWithEffect(tgui::ShowEffectType::SlideToTop, std::chrono::milliseconds(300)); REQUIRE(widget->getPosition() == tgui::Vector2f(30, 15)); widget->updateTime(std::chrono::milliseconds(100)); - compareVector2f(widget->getPosition(), {30, 15.f-((30.f+15.f)/3.f)}); + REQUIRE(compareVector2f(widget->getPosition(), {30, 15.f-((30.f+15.f)/3.f)})); } // The widget is hidden but reset to its original values at the end of the animation diff --git a/tests/Layouts.cpp b/tests/Layouts.cpp index 37ebbb2fc..3fdf0986b 100644 --- a/tests/Layouts.cpp +++ b/tests/Layouts.cpp @@ -506,10 +506,6 @@ TEST_CASE("[Layouts]") { auto parent = tgui::Panel::create({100, 100}); - auto compareVector2f = [](tgui::Vector2f left, tgui::Vector2f right) { - return (std::fabs(left.x - right.x) < 0.00001f) && (std::fabs(left.y - right.y) < 0.00001f); - }; - SECTION("All layouts") { auto leftmost1 = tgui::Panel::create({"2%", 0}); diff --git a/tests/Tests.cpp b/tests/Tests.cpp index 9eccd3762..6ebef8983 100644 --- a/tests/Tests.cpp +++ b/tests/Tests.cpp @@ -22,6 +22,8 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include + #include #ifdef TGUI_SYSTEM_WINDOWS #include @@ -29,6 +31,13 @@ #include "Tests.hpp" +bool compareVector2f(tgui::Vector2f left, tgui::Vector2f right) +{ + const float epsilonX = std::max(0.000001f, std::max(std::abs(left.x), std::abs(right.x)) / 1000000.0f); + const float epsilonY = std::max(0.000001f, std::max(std::abs(left.y), std::abs(right.y)) / 1000000.0f); + return (std::fabs(left.x - right.x) < epsilonX) && (std::fabs(left.y - right.y) < epsilonY); +} + tgui::String getClipboardContents() { #ifdef TGUI_SYSTEM_WINDOWS diff --git a/tests/Tests.hpp b/tests/Tests.hpp index 971e3fd5a..5b618e33a 100644 --- a/tests/Tests.hpp +++ b/tests/Tests.hpp @@ -130,6 +130,7 @@ static const std::chrono::milliseconds DOUBLE_CLICK_TIMEOUT = std::chrono::milli bool compareFiles(const tgui::String& leftFileName, const tgui::String& rightFileName); void compareImageFiles(const tgui::String& filename1, const tgui::String& filename2); +bool compareVector2f(tgui::Vector2f left, tgui::Vector2f right); tgui::String getClipboardContents(); diff --git a/tests/Widgets/Canvas.cpp b/tests/Widgets/Canvas.cpp index 603a526ab..6942f21e2 100644 --- a/tests/Widgets/Canvas.cpp +++ b/tests/Widgets/Canvas.cpp @@ -115,8 +115,9 @@ TEST_CASE("[CanvasSFML]") SECTION("view") { canvas = tgui::CanvasSFML::create({300, 200}); - canvas->setSize({50, 30}); - canvas->setSize({200, 100}); + canvas->setSize({50, 30}); // Test shrinking size + canvas->setSize({200, 100}); // Test expanding size + canvas->setPosition({80, 70}); // Position should not affect results REQUIRE(canvas->getView() == sf::View(sf::FloatRect{{0, 0}, {200, 100}})); REQUIRE(canvas->getDefaultView() == sf::View(sf::FloatRect{{0, 0}, {200, 100}})); @@ -131,6 +132,9 @@ TEST_CASE("[CanvasSFML]") view.setViewport({{0.1f, 0.2f}, {0.5f, 0.6f}}); canvas->setView(view); REQUIRE(canvas->getViewport() == tgui::IntRect(20, 20, 100, 60)); + + REQUIRE(compareVector2f(canvas->mapPixelToCoords({60, 50}), {60, 35})); + REQUIRE(compareVector2f(canvas->mapCoordsToPixel({60, 35}), {60, 50})); } SECTION("Smooth") From fd1ae269b6be945292e22b44598be00127cd5aa4 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 12 Mar 2025 22:32:18 +0100 Subject: [PATCH 61/87] Add tgui::literals::percent namespace that holds the '_percent' literal so you can create layouts with values like 60_percent (closes #253) --- changelog.md | 1 + include/TGUI/AbsoluteOrRelativeValue.hpp | 20 ++++++++++++++++++++ tests/Layouts.cpp | 14 ++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/changelog.md b/changelog.md index 066f6016c..f548a4f86 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ TGUI 1.9 (TBD) --------------- - Added mapPixelToCoords and mapCoordsToPixel to CanvasSFML +- Added tgui::literals::percent namespace with the "_percent" user-defined literal - Fixed behavior of using showWithEffect or hideWithEffect with a Fade type while another fade animation wasn't finished yet diff --git a/include/TGUI/AbsoluteOrRelativeValue.hpp b/include/TGUI/AbsoluteOrRelativeValue.hpp index f70d3db4f..165d75ae9 100644 --- a/include/TGUI/AbsoluteOrRelativeValue.hpp +++ b/include/TGUI/AbsoluteOrRelativeValue.hpp @@ -176,6 +176,26 @@ TGUI_MODULE_EXPORT namespace tgui }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Allow writing 50_percent instead of RelativeValue(0.5) after adding "using namespace tgui::literals::percent;" + // This can also be used in layouts, where you can replace e.g. the "40%" string with 40_percent to skip string parsing + namespace literals + { + inline namespace percent + { + constexpr RelativeValue operator""_percent(long double n) + { + return RelativeValue{static_cast(n / 100.0)}; + } + + constexpr RelativeValue operator""_percent(unsigned long long n) + { + return RelativeValue{static_cast(n) / 100.f}; + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/Layouts.cpp b/tests/Layouts.cpp index 3fdf0986b..28dbb0ac7 100644 --- a/tests/Layouts.cpp +++ b/tests/Layouts.cpp @@ -864,6 +864,20 @@ TEST_CASE("[Layouts]") } } + SECTION("literals::percent") + { + using namespace tgui::literals::percent; + + Layout layout{20_percent}; + REQUIRE(layout.toString() == "20%"); + + Layout layout2{22.7_percent}; + REQUIRE(layout2.toString() == "22.7%"); + + REQUIRE(!layout.isConstant()); + REQUIRE(!layout2.isConstant()); + } + SECTION("Bug Fixes") { SECTION("Setting negative size and reverting back to positive (https://github.com/texus/TGUI/issues/54)") From a9cb3cb23279f398d520eba9db73a8f9049fb8f8 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 12 Mar 2025 22:47:16 +0100 Subject: [PATCH 62/87] Changes in CanvasSFML weren't compatible with SFML 2 --- src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp index 55d8ba3bd..18580ef5b 100644 --- a/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp +++ b/src/Backend/Renderer/SFML-Graphics/CanvasSFML.cpp @@ -195,8 +195,13 @@ namespace tgui const sf::FloatRect& viewport = view.getViewport(); const sf::Vector2f normalized = { +#if SFML_VERSION_MAJOR >= 3 -1 + (2 * (point.x - (viewport.position.x * size.x)) / (viewport.size.x * size.x)), 1 + (-2 * (point.y - (viewport.position.y * size.y)) / (viewport.size.y * size.y)) +#else + -1 + (2 * (point.x - (viewport.left * size.x)) / (viewport.width * size.x)), + 1 + (-2 * (point.y - (viewport.top * size.y)) / (viewport.height * size.y)) +#endif }; const sf::Vector2f coord = view.getInverseTransform().transformPoint(normalized); return {coord.x, coord.y}; @@ -211,8 +216,13 @@ namespace tgui const sf::FloatRect& viewport = view.getViewport(); const sf::Vector2f normalized = view.getTransform().transformPoint(coord); +#if SFML_VERSION_MAJOR >= 3 return {(normalized.x + 1) / 2 * (viewport.size.x * size.x) + (viewport.position.x * size.x), (-normalized.y + 1) / 2 * (viewport.size.y * size.y) + (viewport.position.y * size.y)}; +#else + return {(normalized.x + 1) / 2 * (viewport.width * size.x) + (viewport.left * size.x), + (-normalized.y + 1) / 2 * (viewport.height * size.y) + (viewport.top * size.y)}; +#endif } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 6fbbbe583d443981d1cc7bd50d8eb703c81a786e Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 12 Mar 2025 22:48:19 +0100 Subject: [PATCH 63/87] literals namespace for percent couldn't be non-inline because for StringView there already exists an inline namespace literals --- include/TGUI/AbsoluteOrRelativeValue.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/TGUI/AbsoluteOrRelativeValue.hpp b/include/TGUI/AbsoluteOrRelativeValue.hpp index 165d75ae9..6caf3a67b 100644 --- a/include/TGUI/AbsoluteOrRelativeValue.hpp +++ b/include/TGUI/AbsoluteOrRelativeValue.hpp @@ -179,7 +179,7 @@ TGUI_MODULE_EXPORT namespace tgui // Allow writing 50_percent instead of RelativeValue(0.5) after adding "using namespace tgui::literals::percent;" // This can also be used in layouts, where you can replace e.g. the "40%" string with 40_percent to skip string parsing - namespace literals + inline namespace literals { inline namespace percent { From 7660ecf7cb679cd835147bfdda908a528181c650 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Wed, 12 Mar 2025 22:58:09 +0100 Subject: [PATCH 64/87] Clang complains about 'double' to 'long double' conversion --- include/TGUI/AbsoluteOrRelativeValue.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/TGUI/AbsoluteOrRelativeValue.hpp b/include/TGUI/AbsoluteOrRelativeValue.hpp index 6caf3a67b..79cc89d91 100644 --- a/include/TGUI/AbsoluteOrRelativeValue.hpp +++ b/include/TGUI/AbsoluteOrRelativeValue.hpp @@ -185,7 +185,7 @@ TGUI_MODULE_EXPORT namespace tgui { constexpr RelativeValue operator""_percent(long double n) { - return RelativeValue{static_cast(n / 100.0)}; + return RelativeValue{static_cast(n / 100.0L)}; } constexpr RelativeValue operator""_percent(unsigned long long n) From c112cd8ebd27af5760e6ff946bfe959965348ab1 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 23 Mar 2025 09:17:06 +0100 Subject: [PATCH 65/87] Update CI status badge url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 989a0c0d7..92a4abcf2 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ For more information, take a look at the [website](https://tgui.eu). Status ------ -[![CI Github Actions](https://github.com/texus/TGUI/workflows/CI/badge.svg?branch=1.x)](https://github.com/texus/TGUI/actions) +[![CI Github Actions](https://github.com/texus/TGUI/actions/workflows/ci.yml/badge.svg?branch=1.x)](https://github.com/texus/TGUI/actions/workflows/ci.yml) [![Code coverage](https://codecov.io/gh/texus/TGUI/branch/1.x/graph/badge.svg)](https://codecov.io/gh/texus/TGUI/branch/1.x) OS support for each backend: From b15a8cba47eb2bbf2391244bd4034e39f8837341 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Sun, 13 Apr 2025 19:10:05 +0200 Subject: [PATCH 66/87] Added new SDL_GPU backend --- .github/workflows/ci.yml | 38 +- CMakeLists.txt | 22 +- README.md | 2 + changelog.md | 1 + cmake/Dependencies.cmake | 16 +- cmake/TGUIConfig.cmake.in | 2 +- doc/doxyfile.in | 5 +- examples/android/SDL_GPU/.gitignore | 12 + examples/android/SDL_GPU/app/build.gradle.kts | 43 + .../android/SDL_GPU/app/jni/CMakeLists.txt | 22 + .../android/SDL_GPU/app/jni/src/example.cpp | 112 + .../android/SDL_GPU/app/proguard-rules.pro | 17 + .../SDL_GPU/app/src/main/AndroidManifest.xml | 63 + .../src/main/assets/Background-Landscape.png | Bin 0 -> 6117 bytes .../src/main/assets/Background-Portrait.png | Bin 0 -> 6449 bytes .../main/java/org/libsdl/app/HIDDevice.java | 21 + .../app/HIDDeviceBLESteamController.java | 655 +++++ .../java/org/libsdl/app/HIDDeviceManager.java | 689 ++++++ .../java/org/libsdl/app/HIDDeviceUSB.java | 318 +++ .../app/src/main/java/org/libsdl/app/SDL.java | 90 + .../main/java/org/libsdl/app/SDLActivity.java | 2189 +++++++++++++++++ .../java/org/libsdl/app/SDLAudioManager.java | 126 + .../org/libsdl/app/SDLControllerManager.java | 849 +++++++ .../java/org/libsdl/app/SDLDummyEdit.java | 66 + .../org/libsdl/app/SDLInputConnection.java | 138 ++ .../main/java/org/libsdl/app/SDLSurface.java | 409 +++ .../src/main/res/mipmap-hdpi/tgui_logo.png | Bin 0 -> 3178 bytes .../src/main/res/mipmap-mdpi/tgui_logo.png | Bin 0 -> 2139 bytes .../src/main/res/mipmap-xhdpi/tgui_logo.png | Bin 0 -> 5005 bytes .../src/main/res/mipmap-xxhdpi/tgui_logo.png | Bin 0 -> 8496 bytes .../src/main/res/mipmap-xxxhdpi/tgui_logo.png | Bin 0 -> 24438 bytes .../app/src/main/res/values/colors.xml | 6 + .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 5 + examples/android/SDL_GPU/build.gradle.kts | 27 + examples/android/SDL_GPU/gradle.properties | 17 + .../SDL_GPU/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43705 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + examples/android/SDL_GPU/gradlew | 251 ++ examples/android/SDL_GPU/gradlew.bat | 94 + examples/android/SDL_GPU/settings.gradle.kts | 1 + examples/android/SDL_RENDERER/.gitignore | 2 + .../android/SDL_RENDERER/app/build.gradle | 41 - .../android/SDL_RENDERER/app/build.gradle.kts | 43 + .../{build.gradle => build.gradle.kts} | 18 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 43705 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 +- examples/android/SDL_RENDERER/gradlew | 309 ++- examples/android/SDL_RENDERER/gradlew.bat | 88 +- examples/android/SDL_RENDERER/settings.gradle | 1 - .../android/SDL_RENDERER/settings.gradle.kts | 1 + examples/android/SFML_GRAPHICS/.gitignore | 13 +- .../SFML_GRAPHICS/app/build.gradle.kts | 4 +- examples/main-SDL_GLES2.cpp | 4 +- examples/main-SDL_GPU.cpp | 63 + examples/main-SDL_OPENGL3.cpp | 4 +- examples/main-SDL_RENDERER.cpp | 4 +- examples/main-SDL_TTF_GLES2.cpp | 4 +- examples/main-SDL_TTF_OPENGL3.cpp | 4 +- gui-builder/src/main.cpp | 2 +- .../TGUI/Backend/Renderer/BackendTexture.hpp | 5 +- .../SDL_GPU/BackendRenderTargetSDLGPU.hpp | 175 ++ .../SDL_GPU/BackendRendererSDLGPU.hpp | 93 + .../Renderer/SDL_GPU/BackendTextureSDLGPU.hpp | 103 + .../Backend/Renderer/SDL_GPU/CanvasSDLGPU.hpp | 167 ++ include/TGUI/Backend/SDL-GPU.hpp | 136 + include/TGUI/Backend/Window/BackendGui.hpp | 2 +- .../TGUI/Backend/Window/SDL/BackendGuiSDL.hpp | 5 + include/TGUI/Config.hpp.in | 6 +- include/TGUI/Global.hpp | 30 + include/TGUI/Transform.hpp | 6 +- src/Backend/CMakeLists.txt | 56 +- .../Font/SDL_ttf/BackendFontSDLttf.cpp | 2 - .../Font/SFML-Graphics/BackendFontSFML.cpp | 2 - src/Backend/Renderer/BackendRenderTarget.cpp | 1 - src/Backend/Renderer/BackendTexture.cpp | 7 - src/Backend/Renderer/OpenGL.cppm | 2 +- .../SDL_GPU/BackendRenderTargetSDLGPU.cpp | 775 ++++++ .../SDL_GPU/BackendRendererSDLGPU.cpp | 73 + .../Renderer/SDL_GPU/BackendTextureSDLGPU.cpp | 121 + src/Backend/Renderer/SDL_GPU/CanvasSDLGPU.cpp | 168 ++ .../Renderer/SDL_GPU/shaders/.gitignore | 3 + .../SDL_GPU/shaders/compile_shaders.sh | 32 + .../Renderer/SDL_GPU/shaders/shader.frag.hlsl | 13 + .../Renderer/SDL_GPU/shaders/shader.vert.hlsl | 22 + src/Backend/SDL-GPU.cpp | 117 + src/Backend/Window/SDL/BackendGuiSDL.cpp | 13 +- src/Backend/Window/SDL/BackendSDL.cpp | 5 + src/CMakeLists.txt | 9 +- src/DefaultBackendWindow.cpp | 67 +- src/FileDialogIconLoaderLinux.cpp | 2 +- src/Loading/Serializer.cpp | 1 - src/Signal.cpp | 1 - src/TGUI-Main-Module.cppm.in | 4 +- src/TGUI-Module.cppm.in | 2 +- src/Transform.cpp | 8 - src/Widgets/ListView.cpp | 1 - src/Widgets/RichTextLabel.cpp | 1 - src/Widgets/TreeView.cpp | 1 - tests/Clipping.cpp | 14 +- tests/Tests.cpp | 155 ++ tests/Tests.hpp | 35 +- tests/Widget.cpp | 9 +- tests/Widgets/Canvas.cpp | 55 + tests/main.cpp | 50 +- 105 files changed, 9146 insertions(+), 335 deletions(-) create mode 100644 examples/android/SDL_GPU/.gitignore create mode 100644 examples/android/SDL_GPU/app/build.gradle.kts create mode 100644 examples/android/SDL_GPU/app/jni/CMakeLists.txt create mode 100644 examples/android/SDL_GPU/app/jni/src/example.cpp create mode 100644 examples/android/SDL_GPU/app/proguard-rules.pro create mode 100644 examples/android/SDL_GPU/app/src/main/AndroidManifest.xml create mode 100644 examples/android/SDL_GPU/app/src/main/assets/Background-Landscape.png create mode 100644 examples/android/SDL_GPU/app/src/main/assets/Background-Portrait.png create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDevice.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceManager.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDL.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLActivity.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLAudioManager.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLControllerManager.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLDummyEdit.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLInputConnection.java create mode 100644 examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLSurface.java create mode 100644 examples/android/SDL_GPU/app/src/main/res/mipmap-hdpi/tgui_logo.png create mode 100644 examples/android/SDL_GPU/app/src/main/res/mipmap-mdpi/tgui_logo.png create mode 100644 examples/android/SDL_GPU/app/src/main/res/mipmap-xhdpi/tgui_logo.png create mode 100644 examples/android/SDL_GPU/app/src/main/res/mipmap-xxhdpi/tgui_logo.png create mode 100644 examples/android/SDL_GPU/app/src/main/res/mipmap-xxxhdpi/tgui_logo.png create mode 100644 examples/android/SDL_GPU/app/src/main/res/values/colors.xml create mode 100644 examples/android/SDL_GPU/app/src/main/res/values/strings.xml create mode 100644 examples/android/SDL_GPU/app/src/main/res/values/styles.xml create mode 100644 examples/android/SDL_GPU/build.gradle.kts create mode 100644 examples/android/SDL_GPU/gradle.properties create mode 100644 examples/android/SDL_GPU/gradle/wrapper/gradle-wrapper.jar create mode 100644 examples/android/SDL_GPU/gradle/wrapper/gradle-wrapper.properties create mode 100755 examples/android/SDL_GPU/gradlew create mode 100644 examples/android/SDL_GPU/gradlew.bat create mode 100644 examples/android/SDL_GPU/settings.gradle.kts delete mode 100644 examples/android/SDL_RENDERER/app/build.gradle create mode 100644 examples/android/SDL_RENDERER/app/build.gradle.kts rename examples/android/SDL_RENDERER/{build.gradle => build.gradle.kts} (53%) delete mode 100644 examples/android/SDL_RENDERER/settings.gradle create mode 100644 examples/android/SDL_RENDERER/settings.gradle.kts create mode 100644 examples/main-SDL_GPU.cpp create mode 100644 include/TGUI/Backend/Renderer/SDL_GPU/BackendRenderTargetSDLGPU.hpp create mode 100644 include/TGUI/Backend/Renderer/SDL_GPU/BackendRendererSDLGPU.hpp create mode 100644 include/TGUI/Backend/Renderer/SDL_GPU/BackendTextureSDLGPU.hpp create mode 100644 include/TGUI/Backend/Renderer/SDL_GPU/CanvasSDLGPU.hpp create mode 100644 include/TGUI/Backend/SDL-GPU.hpp create mode 100644 src/Backend/Renderer/SDL_GPU/BackendRenderTargetSDLGPU.cpp create mode 100644 src/Backend/Renderer/SDL_GPU/BackendRendererSDLGPU.cpp create mode 100644 src/Backend/Renderer/SDL_GPU/BackendTextureSDLGPU.cpp create mode 100644 src/Backend/Renderer/SDL_GPU/CanvasSDLGPU.cpp create mode 100644 src/Backend/Renderer/SDL_GPU/shaders/.gitignore create mode 100755 src/Backend/Renderer/SDL_GPU/shaders/compile_shaders.sh create mode 100644 src/Backend/Renderer/SDL_GPU/shaders/shader.frag.hlsl create mode 100644 src/Backend/Renderer/SDL_GPU/shaders/shader.vert.hlsl create mode 100644 src/Backend/SDL-GPU.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaf13fbdc..77291fd95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,6 +204,7 @@ jobs: -DTGUI_BACKEND=Custom -DTGUI_HAS_BACKEND_SFML_GRAPHICS=ON -DTGUI_HAS_BACKEND_SFML_OPENGL3=ON + -DTGUI_HAS_BACKEND_SDL_GPU=ON -DTGUI_HAS_BACKEND_SDL_RENDERER=ON -DTGUI_HAS_BACKEND_SDL_OPENGL3=ON -DTGUI_HAS_BACKEND_SDL_GLES2=ON @@ -616,6 +617,7 @@ jobs: -DTGUI_BUILD_TESTS=ON -DTGUI_BACKEND=Custom -DTGUI_HAS_BACKEND_SFML_GRAPHICS=ON + -DTGUI_HAS_BACKEND_SDL_GPU=ON -DTGUI_HAS_BACKEND_SDL_RENDERER=ON -DTGUI_HAS_BACKEND_GLFW_OPENGL3=ON -DTGUI_HAS_BACKEND_RAYLIB=ON @@ -851,7 +853,7 @@ jobs: - name: Install dependencies run: | - brew install sfml sdl2 sdl2_ttf glfw ninja raylib + brew install sfml sdl2 sdl2_ttf sdl3 sdl3_ttf glfw raylib - name: Build TGUI (dylibs) run: > @@ -861,6 +863,7 @@ jobs: -DBUILD_SHARED_LIBS=ON -DTGUI_BUILD_FRAMEWORK=OFF -DTGUI_CXX_STANDARD=14 + -DTGUI_USE_SDL3=OFF -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_EXAMPLES=OFF -DTGUI_BUILD_GUI_BUILDER=OFF @@ -889,6 +892,7 @@ jobs: -DBUILD_SHARED_LIBS=ON -DTGUI_BUILD_FRAMEWORK=ON -DTGUI_CXX_STANDARD=17 + -DTGUI_USE_SDL3=ON -DTGUI_WARNINGS_AS_ERRORS=ON -DTGUI_BUILD_EXAMPLES=ON -DTGUI_BUILD_GUI_BUILDER=ON @@ -896,6 +900,7 @@ jobs: -DTGUI_BACKEND=Custom -DTGUI_HAS_BACKEND_SFML_GRAPHICS=ON -DTGUI_HAS_BACKEND_SFML_OPENGL3=ON + -DTGUI_HAS_BACKEND_SDL_GPU=ON -DTGUI_HAS_BACKEND_SDL_RENDERER=ON -DTGUI_HAS_BACKEND_SDL_OPENGL3=ON -DTGUI_HAS_BACKEND_SDL_TTF_OPENGL3=ON @@ -933,9 +938,8 @@ jobs: - name: Build SDL_RENDERER project working-directory: TGUI/examples/android/SDL_RENDERER run: | - sed -i "s/^\(\s*\)abiFilters .*$/\1abiFilters 'arm64-v8a'/" app/build.gradle - sed -i "s/^\(\s*\)ndkVersion .*$/\1ndkVersion '${ANDROID_NDK_ROOT##*/}'/" app/build.gradle - ./gradlew assembleRelease --info + sed -i "s/^\(\s*\)abiFilters.add(\"x86_64\").*$/\1\/\/abiFilters.add(\"x86_64\")/" app/build.gradle.kts + ./gradlew assembleRelease -P NDK_VERSION=${ANDROID_NDK_ROOT##*/} --info - name: Build SDL_TTF_GLES2 project working-directory: TGUI/examples/android/SDL_TTF_GLES2 @@ -950,6 +954,30 @@ jobs: #---------------------------------------- + android-sdl-gpu: + runs-on: ubuntu-latest + env: + SDL_VERSION: 3.2.10 + SDL_TTF_VERSION: 3.2.2 + steps: + - name: Checkout TGUI + uses: actions/checkout@v4 + with: + path: TGUI + + - name: Download SDL + run: | + git clone --revision release-$SDL_VERSION --depth 1 https://github.com/libsdl-org/SDL SDL3 + git clone --revision release-$SDL_TTF_VERSION --depth 1 --recurse-submodules --shallow-submodules https://github.com/libsdl-org/SDL_ttf SDL3_ttf + echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "cmake;3.22.1" + + - name: Build SDL_GPU project + working-directory: TGUI/examples/android/SDL_GPU + run: | + ./gradlew assembleRelease -P NDK_VERSION=${ANDROID_NDK_ROOT##*/} --info + + #---------------------------------------- + android-sfml-graphics: runs-on: ubuntu-latest env: @@ -1144,7 +1172,7 @@ jobs: # I've decided to just put the nightly build code in this file as well. nightly-build-windows-visual-studio: if: github.event_name == 'push' && github.ref == 'refs/heads/1.x' - needs: [linux, linux-latest-dev, linux-oldest, linux-per-backend, windows, windows-oldest, windows-clang, windows-static-mt, macos, android-sdl, android-sfml-graphics, ios-sfml-graphics, ios-sdl] + needs: [linux, linux-latest-dev, linux-oldest, linux-per-backend, windows, windows-oldest, windows-clang, windows-static-mt, macos, android-sdl, android-sdl-gpu, android-sfml-graphics, ios-sfml-graphics, ios-sdl] runs-on: windows-2019 env: SFML_VERSION: 3.0.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a39bcb92..3d39aea29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ # If the cmake version is higher than the minimum version then enable all new policies, up to the maximum version specified. # When cmake is newer than the highest version then its newest policies will still be set to the old behavior for compatibility. -cmake_minimum_required(VERSION 3.16...3.31) +cmake_minimum_required(VERSION 3.16...4.0) # Include macros such as tgui_set_option include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Macros.cmake) @@ -104,25 +104,29 @@ if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS) list(APPEND TGUI_BACKEND_OPTIONS SFML_OPENGL3) string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SFML_OPENGL3: sfml-window + OpenGL + FreeType\n") endif() +if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS OR TGUI_OS_ANDROID OR TGUI_OS_IOS) + list(APPEND TGUI_BACKEND_OPTIONS SDL_GPU) + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_GPU: SDL + SDL_ttf\n") +endif() if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS OR TGUI_OS_ANDROID OR TGUI_OS_IOS) list(APPEND TGUI_BACKEND_OPTIONS SDL_RENDERER) - string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_RENDERER: SDL2 + SDL_ttf\n") + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_RENDERER: SDL + SDL_ttf\n") endif() if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS) list(APPEND TGUI_BACKEND_OPTIONS SDL_OPENGL3) - string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_OPENGL3: SDL2 + OpenGL + FreeType\n") + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_OPENGL3: SDL + OpenGL + FreeType\n") endif() if(TGUI_OS_LINUX) list(APPEND TGUI_BACKEND_OPTIONS SDL_GLES2) - string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_GLES2: SDL2 + OpenGL ES + FreeType\n") + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_GLES2: SDL + OpenGL ES + FreeType\n") endif() if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS) list(APPEND TGUI_BACKEND_OPTIONS SDL_TTF_OPENGL3) - string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_TTF_OPENGL3: SDL2 + OpenGL + SDL2_ttf\n") + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_TTF_OPENGL3: SDL + OpenGL + SDL_ttf\n") endif() if(TGUI_OS_LINUX OR TGUI_OS_ANDROID OR TGUI_OS_IOS) list(APPEND TGUI_BACKEND_OPTIONS SDL_TTF_GLES2) - string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_TTF_GLES2: SDL2 + OpenGL ES + SDL2_ttf\n") + string(APPEND TGUI_BACKEND_OPTIONS_DESC " - SDL_TTF_GLES2: SDL + OpenGL ES + SDL_ttf\n") endif() if(TGUI_OS_WINDOWS OR TGUI_OS_LINUX OR TGUI_OS_MACOS) list(APPEND TGUI_BACKEND_OPTIONS GLFW_OPENGL3) @@ -232,8 +236,10 @@ set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib") if (NOT DEFINED TGUI_INSTALL) if ((DEFINED SDL2_DISABLE_INSTALL AND SDL2_DISABLE_INSTALL) OR (DEFINED SDL_DISABLE_INSTALL AND SDL_DISABLE_INSTALL) + OR (DEFINED SDL_INSTALL AND NOT SDL_INSTALL) OR (DEFINED SDL2TTF_INSTALL AND NOT SDL2TTF_INSTALL) OR (DEFINED SDL3TTF_INSTALL AND NOT SDL3TTF_INSTALL) + OR (DEFINED SDLTTF_INSTALL AND NOT SDLTTF_INSTALL) OR (DEFINED GLFW_INSTALL AND NOT GLFW_INSTALL)) set(TGUI_INSTALL OFF) else() @@ -279,7 +285,7 @@ if(TGUI_DEFAULT_BACKEND STREQUAL "SFML_GRAPHICS" OR TGUI_DEFAULT_BACKEND STREQUA target_link_libraries(tgui-console-app-interface INTERFACE sfml-main) endif() endif() -elseif(TGUI_DEFAULT_BACKEND STREQUAL "SDL_RENDERER" +elseif(TGUI_DEFAULT_BACKEND STREQUAL "SDL_GPU" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_RENDERER" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_OPENGL3" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_GLES2" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_TTF_OPENGL3" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_TTF_GLES2") tgui_find_dependency_sdl() @@ -302,7 +308,7 @@ if(TGUI_DEFAULT_BACKEND STREQUAL "SFML_GRAPHICS" OR TGUI_DEFAULT_BACKEND STREQUA target_link_libraries(tgui-gui-app-interface INTERFACE sfml-main) endif() endif() -elseif(TGUI_DEFAULT_BACKEND STREQUAL "SDL_RENDERER" +elseif(TGUI_DEFAULT_BACKEND STREQUAL "SDL_GPU" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_RENDERER" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_OPENGL3" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_GLES2" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_TTF_OPENGL3" OR TGUI_DEFAULT_BACKEND STREQUAL "SDL_TTF_GLES2") tgui_find_dependency_sdl() diff --git a/README.md b/README.md index 92a4abcf2..cb62b0028 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ OS support for each backend: |:------------------------|:-------------------:|:-------------------:|:-------------------:|:-------------------:|:-------------------:| | **SFML\_GRAPHICS** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: :question: | | **SFML\_OPENGL3** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | +| **SDL\_GPU** | :heavy_check_mark: | :heavy_check_mark: | :question: | :heavy_check_mark: | :question: | | **SDL\_RENDERER** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: :question: | | **SDL\_TTF\_OPENGL3** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | | **SDL\_TTF\_GLES2** | | :heavy_check_mark: | N/A | :heavy_check_mark: | :heavy_check_mark: :question: | @@ -37,6 +38,7 @@ Dependencies for each backend: |:------------------------|:----------------------|:------------------------|:------------------------| | **SFML\_GRAPHICS** | sfml-window (>= 2.5) | sfml-graphics (>= 2.5) | sfml-graphics (>= 2.5) | | **SFML\_OPENGL3** | sfml-window (>= 2.5) | FreeType (>= 2.6) | OpenGL (>= 3.3) | +| **SDL\_GPU** | SDL (>= 3.2) | SDL_ttf (>= 3.2) | SDL (>= 3.2) | | **SDL\_RENDERER** | SDL (>= 2.0.18) | SDL_ttf (>= 2.0.14) | SDL (>= 2.0.18) | | **SDL\_TTF\_OPENGL3** | SDL (>= 2.0.6) | SDL_ttf (>= 2.0.14) | OpenGL (>= 3.3) | | **SDL\_TTF\_GLES2** | SDL (>= 2.0.6) | SDL_ttf (>= 2.0.14) | OpenGL ES (>= 2.0) | diff --git a/changelog.md b/changelog.md index f548a4f86..3c5c07843 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ TGUI 1.9 (TBD) --------------- +- New backend: SDL_GPU (uses SDL3's new GPU API) - Added mapPixelToCoords and mapCoordsToPixel to CanvasSFML - Added tgui::literals::percent namespace with the "_percent" user-defined literal - Fixed behavior of using showWithEffect or hideWithEffect with a Fade type while another fade animation wasn't finished yet diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 9f16b59c1..ac8b87b70 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -110,6 +110,7 @@ function(tgui_try_find_sdl3) if(SDL3_FOUND) set(TGUI_FOUND_SDL3 TRUE PARENT_SCOPE) + set(SDL3_VERSION "${SDL3_VERSION}" PARENT_SCOPE) else() set(TGUI_FOUND_SDL3 FALSE PARENT_SCOPE) endif() @@ -168,7 +169,7 @@ macro(tgui_find_dependency_sdl) # An option is added to explicitly search for the other version, in case the default decision is unwanted. if(NOT DEFINED TGUI_USE_SDL3) set(description "Determines whether TGUI looks for SDL2 or SDL3") - if(TGUI_FOUND_SDL3) + if(TGUI_FOUND_SDL3 OR TGUI_HAS_BACKEND_SDL_GPU OR TGUI_CUSTOM_BACKEND_HAS_RENDERER_SDL_GPU) option(TGUI_USE_SDL3 "${description}" TRUE) elseif(TGUI_FOUND_SDL2_CONFIG OR TGUI_FOUND_SDL2_MODULE) option(TGUI_USE_SDL3 "${description}" FALSE) @@ -181,6 +182,10 @@ macro(tgui_find_dependency_sdl) endif() endif() + if(NOT TGUI_USE_SDL3 AND (TGUI_HAS_BACKEND_SDL_GPU OR TGUI_CUSTOM_BACKEND_HAS_RENDERER_SDL_GPU)) + message(FATAL_ERROR "SDL_GPU backend requires SDL3. Change the value of TGUI_USE_SDL3 or select a different backend.") + endif() + if(TGUI_USE_SDL3) if(NOT TARGET SDL3::SDL3) # Only search if the target wasn't defined yet if(TGUI_FOUND_SDL3) @@ -193,6 +198,15 @@ macro(tgui_find_dependency_sdl) endif() endif() + if(DEFINED SDL3_VERSION) + # Check that the minimum SDL version is met when using the SDL GPU API + if(TGUI_HAS_BACKEND_SDL_GPU OR TGUI_CUSTOM_BACKEND_HAS_RENDERER_SDL_GPU) + if (SDL3_VERSION VERSION_LESS 3.2.0) + message(FATAL_ERROR "SDL 3.2.0 or higher is required for SDL_GPU backend") + endif() + endif() + endif() + # We don't need to keep options that were created for SDL2 unset(SDL2_DIR CACHE) unset(SDL2_PATH CACHE) diff --git a/cmake/TGUIConfig.cmake.in b/cmake/TGUIConfig.cmake.in index 173d61aa4..99798cacd 100644 --- a/cmake/TGUIConfig.cmake.in +++ b/cmake/TGUIConfig.cmake.in @@ -132,7 +132,7 @@ if(NOT TARGET raylib AND (@TGUI_HAS_WINDOW_BACKEND_RAYLIB@ OR @TGUI_HAS_FONT_BAC endif() # Search for SDL when a backend requires it -if(@TGUI_HAS_WINDOW_BACKEND_SDL@ OR @TGUI_HAS_FONT_BACKEND_SDL_TTF@ OR @TGUI_HAS_RENDERER_BACKEND_SDL_RENDERER@) +if(@TGUI_HAS_WINDOW_BACKEND_SDL@ OR @TGUI_HAS_FONT_BACKEND_SDL_TTF@ OR @TGUI_HAS_RENDERER_BACKEND_SDL_GPU@ OR @TGUI_HAS_RENDERER_BACKEND_SDL_RENDERER@) if(@TGUI_USE_SDL3@) if (NOT TARGET SDL3::SDL3) find_dependency(SDL3 CONFIG) diff --git a/doc/doxyfile.in b/doc/doxyfile.in index 86be483e7..7b943289d 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -32,6 +32,7 @@ INPUT = "@PROJECT_SOURCE_DIR@/include/TGUI" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/GLES2" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/OpenGL3" \ + "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/SDL_GPU" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/SDL_Renderer" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/SFML-Graphics" \ "@PROJECT_SOURCE_DIR@/include/TGUI/Backend/Renderer/Raylib" \ @@ -75,6 +76,7 @@ PREDEFINED = TGUI_DEPRECATED(x)= \ TGUI_HAS_WINDOW_BACKEND_GLFW=1 \ TGUI_HAS_WINDOW_BACKEND_RAYLIB=1 \ TGUI_HAS_RENDERER_BACKEND_SFML_GRAPHICS=1 \ + TGUI_HAS_RENDERER_BACKEND_SDL_GPU=1 \ TGUI_HAS_RENDERER_BACKEND_SDL_RENDERER=1 \ TGUI_HAS_RENDERER_BACKEND_OPENGL3=1 \ TGUI_HAS_RENDERER_BACKEND_GLES2=1 \ @@ -85,7 +87,7 @@ PREDEFINED = TGUI_DEPRECATED(x)= \ TGUI_HAS_FONT_BACKEND_RAYLIB=1 \ TGUI_HAS_BACKEND_SFML_GRAPHICS=1 \ TGUI_HAS_BACKEND_SFML_OPENGL3=1 \ - TGUI_HAS_BACKEND_SDL_RENDERER=1 \ + TGUI_HAS_BACKEND_SDL_GPU=1 \ TGUI_HAS_BACKEND_SDL_OPENGL3=1 \ TGUI_HAS_BACKEND_SDL_GLES2=1 \ TGUI_HAS_BACKEND_SDL_TTF_OPENGL3=1 \ @@ -94,6 +96,7 @@ PREDEFINED = TGUI_DEPRECATED(x)= \ TGUI_HAS_BACKEND_GLFW_GLES2=1 \ TGUI_HAS_BACKEND_RAYLIB=1 \ SFML_VERSION_MAJOR=3 \ + SDL_MAJOR_VERSION=3 \ TGUI_NODISCARD=[[nodiscard]] SHOW_NAMESPACES = NO diff --git a/examples/android/SDL_GPU/.gitignore b/examples/android/SDL_GPU/.gitignore new file mode 100644 index 000000000..68df15d8f --- /dev/null +++ b/examples/android/SDL_GPU/.gitignore @@ -0,0 +1,12 @@ +/local.properties +/build +/build.sh +/.idea +/.gradle +/app/.externalNativeBuild +/app/.cxx +/app/build +/app/jni/SDL +/app/jni/SDL_image +/app/jni/SDL_ttf +/app/jni/TGUI diff --git a/examples/android/SDL_GPU/app/build.gradle.kts b/examples/android/SDL_GPU/app/build.gradle.kts new file mode 100644 index 000000000..b13c504dd --- /dev/null +++ b/examples/android/SDL_GPU/app/build.gradle.kts @@ -0,0 +1,43 @@ +plugins { + id("com.android.application") +} + +val NDK_VERSION by extra(project.properties["NDK_VERSION"] as? String ?: "28.0.13004108") + +android { + namespace = "org.libsdl.app" + ndkVersion = NDK_VERSION + compileSdk = 34 + defaultConfig { + applicationId = "eu.tgui.app" + minSdk = 29 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + ndk { + abiFilters.add("arm64-v8a") + abiFilters.add("x86_64") + } + externalNativeBuild { + cmake { + arguments.add("-DANDROID_STL=c++_shared") + } + } + } + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + } + } + externalNativeBuild { + cmake { + path("jni/CMakeLists.txt") + version = "3.22.1" + } + } +} + +dependencies { + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) +} diff --git a/examples/android/SDL_GPU/app/jni/CMakeLists.txt b/examples/android/SDL_GPU/app/jni/CMakeLists.txt new file mode 100644 index 000000000..057525c6f --- /dev/null +++ b/examples/android/SDL_GPU/app/jni/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.22) +project(tgui-example CXX) + +set(TGUI_BACKEND SDL_GPU) +set(TGUI_CXX_STANDARD 20) + +set(SDL3_BUILD_DIR SDL-build) +set(SDL3_TTF_BUILD_DIR SDL_ttf-build) + +set(TGUI_ROOT_DIR "../../../../../") + +# Build SDL and SDL_ttf +add_subdirectory("${TGUI_ROOT_DIR}/../SDL3" ${SDL3_BUILD_DIR}) +add_subdirectory("${TGUI_ROOT_DIR}/../SDL3_ttf" ${SDL3_TTF_BUILD_DIR}) + +# Build TGUI +add_subdirectory("${TGUI_ROOT_DIR}" TGUI-build) + +# Create the libmain.so library that contains the application's c++ code. +# The library needs to be called like this because SDLActivity will search for that name. +add_library(main SHARED src/example.cpp) +target_link_libraries(main PRIVATE TGUI::TGUI log) diff --git a/examples/android/SDL_GPU/app/jni/src/example.cpp b/examples/android/SDL_GPU/app/jni/src/example.cpp new file mode 100644 index 000000000..5c2a04f8c --- /dev/null +++ b/examples/android/SDL_GPU/app/jni/src/example.cpp @@ -0,0 +1,112 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TGUI - Texus' Graphical User Interface +// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include + +// The background image will rotate with the screen +void setBackground(tgui::BackendGui& gui, tgui::Vector2f screenSize) +{ + gui.get("Landscape")->setSize(screenSize.x, screenSize.y); + gui.get("Portrait")->setSize(screenSize.x, screenSize.y); + + if (screenSize.x > screenSize.y) + { + gui.get("Landscape")->setVisible(true); + gui.get("Portrait")->setVisible(false); + } + else + { + gui.get("Landscape")->setVisible(false); + gui.get("Portrait")->setVisible(true); + } +} + +bool runExample(tgui::BackendGui& gui) +{ + auto picLandscape = tgui::Picture::create("Background-Landscape.png"); + picLandscape->setSize({"100%", "100%"}); + gui.add(picLandscape, "Landscape"); + + auto picPortrait = tgui::Picture::create("Background-Portrait.png"); + picPortrait->setSize({"100%", "100%"}); + gui.add(picPortrait, "Portrait"); + + // Clicking on this edit box will open the keyboard and allow you to type in it + auto editBox = tgui::EditBox::create(); + editBox->setPosition(50, 150); + editBox->setSize(400, 40); + editBox->setDefaultText("Enter text here..."); + gui.add(editBox); + + // Pressing the button will change the text in the edit box + auto button = tgui::Button::create("Hello"); + button->setPosition(50, 50); + button->setSize(200, 50); + button->onPress([=]{ editBox->setText("World"); }); + gui.add(button); + + // Set the background and let is change depending on the screen orientation. + // As long as we don't manually set a view, the gui view will match the window size. + setBackground(gui, gui.getView().getSize()); + + gui.onViewChange([guiPtr=&gui](tgui::FloatRect view){ + setBackground(*guiPtr, view.getSize()); + }); + + return true; +} + +// We don't put this code in main() to make sure that all TGUI resources are destroyed before destroying SDL +void run_application(SDL_Window* window, SDL_GPUDevice* device) +{ + tgui::Gui gui{window, device}; + if (!runExample(gui)) + return; + + gui.mainLoop(); +} + +int main(int, char**) +{ + SDL_Init(SDL_INIT_VIDEO); + TTF_Init(); + SDL_GPUDevice* device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, false, nullptr); + SDL_Window* window = SDL_CreateWindow("TGUI window with SDL", + 800, 600, // ignored because of SDL_WINDOW_FULLSCREEN_DESKTOP flag + SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE); + SDL_ClaimWindowForGPUDevice(device, window); + + run_application(window, device); + + // All TGUI resources must be destroyed before SDL and SDL_TTF are cleaned up + SDL_ReleaseWindowFromGPUDevice(device, window); + SDL_DestroyWindow(window); + SDL_DestroyGPUDevice(device); + TTF_Quit(); + SDL_Quit(); + return 0; +} diff --git a/examples/android/SDL_GPU/app/proguard-rules.pro b/examples/android/SDL_GPU/app/proguard-rules.pro new file mode 100644 index 000000000..eaf0e916c --- /dev/null +++ b/examples/android/SDL_GPU/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in [sdk]/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/examples/android/SDL_GPU/app/src/main/AndroidManifest.xml b/examples/android/SDL_GPU/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..1d66a4d80 --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/android/SDL_GPU/app/src/main/assets/Background-Landscape.png b/examples/android/SDL_GPU/app/src/main/assets/Background-Landscape.png new file mode 100644 index 0000000000000000000000000000000000000000..68a8c2c52e3dd2164a8eaac2db0368838c011e60 GIT binary patch literal 6117 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

*856>cmTK&y4tdUwPccc(fz4Vgu? zU&Z@brkp2RyFa;v?uz=Z?%_K>4RO>I7*&r6n`po70ayN1!7vnykiC&sVe;Z!iuzK? z&P{OP47sZ1OR37PF6dW_`HMZ)N3^}ePa=TZGK;I`Tt`c8>NMf4&Lzf{(yYq!>43}y`|&8D+vH|Qz5n|E94`|6kbD-OdStxhr;KaaGvm)A<|}Y`mvxC z((5N}g}L{q*mrUq!e#1qUwWzWhzAIl-o?nd5|2?tW%uy>2&6k;Nn7RT9R=s{ji=31 z)i&rM>J6{6+fX*h0=P}Wn+@mjVVF^#Wzbf(~|`44Pya9Q_6qwobx1xhppaI0qxZzZiIyfkwh`UM7P zY`Sowgg)0f_US&`NYnl%n)LbWsUFiOEBd2!?x86}FPRA$lN+qlu-hNiK17B{4ouYW z#b&>dVyoR1o^%H7YGc*G(+Zx2w{3RCe#HfL?As46$c67a$eTY+h^}$;Ey@p!aeCF; v`>xa-v@N89W3+AQyMq};*>z)oMJ3uMuDXH@yng?aL8Yr{sPX=;ee8b#ZJP~R literal 0 HcmV?d00001 diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDevice.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDevice.java new file mode 100644 index 000000000..f96095324 --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDevice.java @@ -0,0 +1,21 @@ +package org.libsdl.app; + +import android.hardware.usb.UsbDevice; + +interface HIDDevice +{ + public int getId(); + public int getVendorId(); + public int getProductId(); + public String getSerialNumber(); + public int getVersion(); + public String getManufacturerName(); + public String getProductName(); + public UsbDevice getDevice(); + public boolean open(); + public int writeReport(byte[] report, boolean feature); + public boolean readReport(byte[] report, boolean feature); + public void setFrozen(boolean frozen); + public void close(); + public void shutdown(); +} diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java new file mode 100644 index 000000000..df4763acc --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java @@ -0,0 +1,655 @@ +package org.libsdl.app; + +import android.content.Context; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothGattService; +import android.hardware.usb.UsbDevice; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.os.*; + +//import com.android.internal.util.HexDump; + +import java.lang.Runnable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.UUID; + +class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDevice { + + private static final String TAG = "hidapi"; + private HIDDeviceManager mManager; + private BluetoothDevice mDevice; + private int mDeviceId; + private BluetoothGatt mGatt; + private boolean mIsRegistered = false; + private boolean mIsConnected = false; + private boolean mIsChromebook = false; + private boolean mIsReconnecting = false; + private boolean mFrozen = false; + private LinkedList mOperations; + GattOperation mCurrentOperation = null; + private Handler mHandler; + + private static final int TRANSPORT_AUTO = 0; + private static final int TRANSPORT_BREDR = 1; + private static final int TRANSPORT_LE = 2; + + private static final int CHROMEBOOK_CONNECTION_CHECK_INTERVAL = 10000; + + static final UUID steamControllerService = UUID.fromString("100F6C32-1735-4313-B402-38567131E5F3"); + static final UUID inputCharacteristic = UUID.fromString("100F6C33-1735-4313-B402-38567131E5F3"); + static final UUID reportCharacteristic = UUID.fromString("100F6C34-1735-4313-B402-38567131E5F3"); + static private final byte[] enterValveMode = new byte[] { (byte)0xC0, (byte)0x87, 0x03, 0x08, 0x07, 0x00 }; + + static class GattOperation { + private enum Operation { + CHR_READ, + CHR_WRITE, + ENABLE_NOTIFICATION + } + + Operation mOp; + UUID mUuid; + byte[] mValue; + BluetoothGatt mGatt; + boolean mResult = true; + + private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid) { + mGatt = gatt; + mOp = operation; + mUuid = uuid; + } + + private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid, byte[] value) { + mGatt = gatt; + mOp = operation; + mUuid = uuid; + mValue = value; + } + + public void run() { + // This is executed in main thread + BluetoothGattCharacteristic chr; + + switch (mOp) { + case CHR_READ: + chr = getCharacteristic(mUuid); + //Log.v(TAG, "Reading characteristic " + chr.getUuid()); + if (!mGatt.readCharacteristic(chr)) { + Log.e(TAG, "Unable to read characteristic " + mUuid.toString()); + mResult = false; + break; + } + mResult = true; + break; + case CHR_WRITE: + chr = getCharacteristic(mUuid); + //Log.v(TAG, "Writing characteristic " + chr.getUuid() + " value=" + HexDump.toHexString(value)); + chr.setValue(mValue); + if (!mGatt.writeCharacteristic(chr)) { + Log.e(TAG, "Unable to write characteristic " + mUuid.toString()); + mResult = false; + break; + } + mResult = true; + break; + case ENABLE_NOTIFICATION: + chr = getCharacteristic(mUuid); + //Log.v(TAG, "Writing descriptor of " + chr.getUuid()); + if (chr != null) { + BluetoothGattDescriptor cccd = chr.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); + if (cccd != null) { + int properties = chr.getProperties(); + byte[] value; + if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == BluetoothGattCharacteristic.PROPERTY_NOTIFY) { + value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE; + } else if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == BluetoothGattCharacteristic.PROPERTY_INDICATE) { + value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE; + } else { + Log.e(TAG, "Unable to start notifications on input characteristic"); + mResult = false; + return; + } + + mGatt.setCharacteristicNotification(chr, true); + cccd.setValue(value); + if (!mGatt.writeDescriptor(cccd)) { + Log.e(TAG, "Unable to write descriptor " + mUuid.toString()); + mResult = false; + return; + } + mResult = true; + } + } + } + } + + public boolean finish() { + return mResult; + } + + private BluetoothGattCharacteristic getCharacteristic(UUID uuid) { + BluetoothGattService valveService = mGatt.getService(steamControllerService); + if (valveService == null) + return null; + return valveService.getCharacteristic(uuid); + } + + static public GattOperation readCharacteristic(BluetoothGatt gatt, UUID uuid) { + return new GattOperation(gatt, Operation.CHR_READ, uuid); + } + + static public GattOperation writeCharacteristic(BluetoothGatt gatt, UUID uuid, byte[] value) { + return new GattOperation(gatt, Operation.CHR_WRITE, uuid, value); + } + + static public GattOperation enableNotification(BluetoothGatt gatt, UUID uuid) { + return new GattOperation(gatt, Operation.ENABLE_NOTIFICATION, uuid); + } + } + + HIDDeviceBLESteamController(HIDDeviceManager manager, BluetoothDevice device) { + mManager = manager; + mDevice = device; + mDeviceId = mManager.getDeviceIDForIdentifier(getIdentifier()); + mIsRegistered = false; + mIsChromebook = mManager.getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); + mOperations = new LinkedList(); + mHandler = new Handler(Looper.getMainLooper()); + + mGatt = connectGatt(); + // final HIDDeviceBLESteamController finalThis = this; + // mHandler.postDelayed(new Runnable() { + // @Override + // void run() { + // finalThis.checkConnectionForChromebookIssue(); + // } + // }, CHROMEBOOK_CONNECTION_CHECK_INTERVAL); + } + + String getIdentifier() { + return String.format("SteamController.%s", mDevice.getAddress()); + } + + BluetoothGatt getGatt() { + return mGatt; + } + + // Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead + // of TRANSPORT_LE. Let's force ourselves to connect low energy. + private BluetoothGatt connectGatt(boolean managed) { + if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) { + try { + return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE); + } catch (Exception e) { + return mDevice.connectGatt(mManager.getContext(), managed, this); + } + } else { + return mDevice.connectGatt(mManager.getContext(), managed, this); + } + } + + private BluetoothGatt connectGatt() { + return connectGatt(false); + } + + protected int getConnectionState() { + + Context context = mManager.getContext(); + if (context == null) { + // We are lacking any context to get our Bluetooth information. We'll just assume disconnected. + return BluetoothProfile.STATE_DISCONNECTED; + } + + BluetoothManager btManager = (BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE); + if (btManager == null) { + // This device doesn't support Bluetooth. We should never be here, because how did + // we instantiate a device to start with? + return BluetoothProfile.STATE_DISCONNECTED; + } + + return btManager.getConnectionState(mDevice, BluetoothProfile.GATT); + } + + void reconnect() { + + if (getConnectionState() != BluetoothProfile.STATE_CONNECTED) { + mGatt.disconnect(); + mGatt = connectGatt(); + } + + } + + protected void checkConnectionForChromebookIssue() { + if (!mIsChromebook) { + // We only do this on Chromebooks, because otherwise it's really annoying to just attempt + // over and over. + return; + } + + int connectionState = getConnectionState(); + + switch (connectionState) { + case BluetoothProfile.STATE_CONNECTED: + if (!mIsConnected) { + // We are in the Bad Chromebook Place. We can force a disconnect + // to try to recover. + Log.v(TAG, "Chromebook: We are in a very bad state; the controller shows as connected in the underlying Bluetooth layer, but we never received a callback. Forcing a reconnect."); + mIsReconnecting = true; + mGatt.disconnect(); + mGatt = connectGatt(false); + break; + } + else if (!isRegistered()) { + if (mGatt.getServices().size() > 0) { + Log.v(TAG, "Chromebook: We are connected to a controller, but never got our registration. Trying to recover."); + probeService(this); + } + else { + Log.v(TAG, "Chromebook: We are connected to a controller, but never discovered services. Trying to recover."); + mIsReconnecting = true; + mGatt.disconnect(); + mGatt = connectGatt(false); + break; + } + } + else { + Log.v(TAG, "Chromebook: We are connected, and registered. Everything's good!"); + return; + } + break; + + case BluetoothProfile.STATE_DISCONNECTED: + Log.v(TAG, "Chromebook: We have either been disconnected, or the Chromebook BtGatt.ContextMap bug has bitten us. Attempting a disconnect/reconnect, but we may not be able to recover."); + + mIsReconnecting = true; + mGatt.disconnect(); + mGatt = connectGatt(false); + break; + + case BluetoothProfile.STATE_CONNECTING: + Log.v(TAG, "Chromebook: We're still trying to connect. Waiting a bit longer."); + break; + } + + final HIDDeviceBLESteamController finalThis = this; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + finalThis.checkConnectionForChromebookIssue(); + } + }, CHROMEBOOK_CONNECTION_CHECK_INTERVAL); + } + + private boolean isRegistered() { + return mIsRegistered; + } + + private void setRegistered() { + mIsRegistered = true; + } + + private boolean probeService(HIDDeviceBLESteamController controller) { + + if (isRegistered()) { + return true; + } + + if (!mIsConnected) { + return false; + } + + Log.v(TAG, "probeService controller=" + controller); + + for (BluetoothGattService service : mGatt.getServices()) { + if (service.getUuid().equals(steamControllerService)) { + Log.v(TAG, "Found Valve steam controller service " + service.getUuid()); + + for (BluetoothGattCharacteristic chr : service.getCharacteristics()) { + if (chr.getUuid().equals(inputCharacteristic)) { + Log.v(TAG, "Found input characteristic"); + // Start notifications + BluetoothGattDescriptor cccd = chr.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); + if (cccd != null) { + enableNotification(chr.getUuid()); + } + } + } + return true; + } + } + + if ((mGatt.getServices().size() == 0) && mIsChromebook && !mIsReconnecting) { + Log.e(TAG, "Chromebook: Discovered services were empty; this almost certainly means the BtGatt.ContextMap bug has bitten us."); + mIsConnected = false; + mIsReconnecting = true; + mGatt.disconnect(); + mGatt = connectGatt(false); + } + + return false; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + private void finishCurrentGattOperation() { + GattOperation op = null; + synchronized (mOperations) { + if (mCurrentOperation != null) { + op = mCurrentOperation; + mCurrentOperation = null; + } + } + if (op != null) { + boolean result = op.finish(); // TODO: Maybe in main thread as well? + + // Our operation failed, let's add it back to the beginning of our queue. + if (!result) { + mOperations.addFirst(op); + } + } + executeNextGattOperation(); + } + + private void executeNextGattOperation() { + synchronized (mOperations) { + if (mCurrentOperation != null) + return; + + if (mOperations.isEmpty()) + return; + + mCurrentOperation = mOperations.removeFirst(); + } + + // Run in main thread + mHandler.post(new Runnable() { + @Override + public void run() { + synchronized (mOperations) { + if (mCurrentOperation == null) { + Log.e(TAG, "Current operation null in executor?"); + return; + } + + mCurrentOperation.run(); + // now wait for the GATT callback and when it comes, finish this operation + } + } + }); + } + + private void queueGattOperation(GattOperation op) { + synchronized (mOperations) { + mOperations.add(op); + } + executeNextGattOperation(); + } + + private void enableNotification(UUID chrUuid) { + GattOperation op = HIDDeviceBLESteamController.GattOperation.enableNotification(mGatt, chrUuid); + queueGattOperation(op); + } + + void writeCharacteristic(UUID uuid, byte[] value) { + GattOperation op = HIDDeviceBLESteamController.GattOperation.writeCharacteristic(mGatt, uuid, value); + queueGattOperation(op); + } + + void readCharacteristic(UUID uuid) { + GattOperation op = HIDDeviceBLESteamController.GattOperation.readCharacteristic(mGatt, uuid); + queueGattOperation(op); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////// BluetoothGattCallback overridden methods + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onConnectionStateChange(BluetoothGatt g, int status, int newState) { + //Log.v(TAG, "onConnectionStateChange status=" + status + " newState=" + newState); + mIsReconnecting = false; + if (newState == 2) { + mIsConnected = true; + // Run directly, without GattOperation + if (!isRegistered()) { + mHandler.post(new Runnable() { + @Override + public void run() { + mGatt.discoverServices(); + } + }); + } + } + else if (newState == 0) { + mIsConnected = false; + } + + // Disconnection is handled in SteamLink using the ACTION_ACL_DISCONNECTED Intent. + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + //Log.v(TAG, "onServicesDiscovered status=" + status); + if (status == 0) { + if (gatt.getServices().size() == 0) { + Log.v(TAG, "onServicesDiscovered returned zero services; something has gone horribly wrong down in Android's Bluetooth stack."); + mIsReconnecting = true; + mIsConnected = false; + gatt.disconnect(); + mGatt = connectGatt(false); + } + else { + probeService(this); + } + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + //Log.v(TAG, "onCharacteristicRead status=" + status + " uuid=" + characteristic.getUuid()); + + if (characteristic.getUuid().equals(reportCharacteristic) && !mFrozen) { + mManager.HIDDeviceReportResponse(getId(), characteristic.getValue()); + } + + finishCurrentGattOperation(); + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + //Log.v(TAG, "onCharacteristicWrite status=" + status + " uuid=" + characteristic.getUuid()); + + if (characteristic.getUuid().equals(reportCharacteristic)) { + // Only register controller with the native side once it has been fully configured + if (!isRegistered()) { + Log.v(TAG, "Registering Steam Controller with ID: " + getId()); + mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true); + setRegistered(); + } + } + + finishCurrentGattOperation(); + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + // Enable this for verbose logging of controller input reports + //Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue())); + + if (characteristic.getUuid().equals(inputCharacteristic) && !mFrozen) { + mManager.HIDDeviceInputReport(getId(), characteristic.getValue()); + } + } + + @Override + public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + //Log.v(TAG, "onDescriptorRead status=" + status); + } + + @Override + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + BluetoothGattCharacteristic chr = descriptor.getCharacteristic(); + //Log.v(TAG, "onDescriptorWrite status=" + status + " uuid=" + chr.getUuid() + " descriptor=" + descriptor.getUuid()); + + if (chr.getUuid().equals(inputCharacteristic)) { + boolean hasWrittenInputDescriptor = true; + BluetoothGattCharacteristic reportChr = chr.getService().getCharacteristic(reportCharacteristic); + if (reportChr != null) { + Log.v(TAG, "Writing report characteristic to enter valve mode"); + reportChr.setValue(enterValveMode); + gatt.writeCharacteristic(reportChr); + } + } + + finishCurrentGattOperation(); + } + + @Override + public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { + //Log.v(TAG, "onReliableWriteCompleted status=" + status); + } + + @Override + public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { + //Log.v(TAG, "onReadRemoteRssi status=" + status); + } + + @Override + public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { + //Log.v(TAG, "onMtuChanged status=" + status); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + //////// Public API + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public int getId() { + return mDeviceId; + } + + @Override + public int getVendorId() { + // Valve Corporation + final int VALVE_USB_VID = 0x28DE; + return VALVE_USB_VID; + } + + @Override + public int getProductId() { + // We don't have an easy way to query from the Bluetooth device, but we know what it is + final int D0G_BLE2_PID = 0x1106; + return D0G_BLE2_PID; + } + + @Override + public String getSerialNumber() { + // This will be read later via feature report by Steam + return "12345"; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public String getManufacturerName() { + return "Valve Corporation"; + } + + @Override + public String getProductName() { + return "Steam Controller"; + } + + @Override + public UsbDevice getDevice() { + return null; + } + + @Override + public boolean open() { + return true; + } + + @Override + public int writeReport(byte[] report, boolean feature) { + if (!isRegistered()) { + Log.e(TAG, "Attempted writeReport before Steam Controller is registered!"); + if (mIsConnected) { + probeService(this); + } + return -1; + } + + if (feature) { + // We need to skip the first byte, as that doesn't go over the air + byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1); + //Log.v(TAG, "writeFeatureReport " + HexDump.dumpHexString(actual_report)); + writeCharacteristic(reportCharacteristic, actual_report); + return report.length; + } else { + //Log.v(TAG, "writeOutputReport " + HexDump.dumpHexString(report)); + writeCharacteristic(reportCharacteristic, report); + return report.length; + } + } + + @Override + public boolean readReport(byte[] report, boolean feature) { + if (!isRegistered()) { + Log.e(TAG, "Attempted readReport before Steam Controller is registered!"); + if (mIsConnected) { + probeService(this); + } + return false; + } + + if (feature) { + readCharacteristic(reportCharacteristic); + return true; + } else { + // Not implemented + return false; + } + } + + @Override + public void close() { + } + + @Override + public void setFrozen(boolean frozen) { + mFrozen = frozen; + } + + @Override + public void shutdown() { + close(); + + BluetoothGatt g = mGatt; + if (g != null) { + g.disconnect(); + g.close(); + mGatt = null; + } + mManager = null; + mIsRegistered = false; + mIsConnected = false; + mOperations.clear(); + } + +} + diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceManager.java new file mode 100644 index 000000000..642a97676 --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -0,0 +1,689 @@ +package org.libsdl.app; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.os.Build; +import android.util.Log; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.hardware.usb.*; +import android.os.Handler; +import android.os.Looper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class HIDDeviceManager { + private static final String TAG = "hidapi"; + private static final String ACTION_USB_PERMISSION = "org.libsdl.app.USB_PERMISSION"; + + private static HIDDeviceManager sManager; + private static int sManagerRefCount = 0; + + static public HIDDeviceManager acquire(Context context) { + if (sManagerRefCount == 0) { + sManager = new HIDDeviceManager(context); + } + ++sManagerRefCount; + return sManager; + } + + static public void release(HIDDeviceManager manager) { + if (manager == sManager) { + --sManagerRefCount; + if (sManagerRefCount == 0) { + sManager.close(); + sManager = null; + } + } + } + + private Context mContext; + private HashMap mDevicesById = new HashMap(); + private HashMap mBluetoothDevices = new HashMap(); + private int mNextDeviceId = 0; + private SharedPreferences mSharedPreferences = null; + private boolean mIsChromebook = false; + private UsbManager mUsbManager; + private Handler mHandler; + private BluetoothManager mBluetoothManager; + private List mLastBluetoothDevices; + + private final BroadcastReceiver mUsbBroadcast = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { + UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + handleUsbDeviceAttached(usbDevice); + } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) { + UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + handleUsbDeviceDetached(usbDevice); + } else if (action.equals(HIDDeviceManager.ACTION_USB_PERMISSION)) { + UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + handleUsbDevicePermission(usbDevice, intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)); + } + } + }; + + private final BroadcastReceiver mBluetoothBroadcast = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + // Bluetooth device was connected. If it was a Steam Controller, handle it + if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Log.d(TAG, "Bluetooth device connected: " + device); + + if (isSteamController(device)) { + connectBluetoothDevice(device); + } + } + + // Bluetooth device was disconnected, remove from controller manager (if any) + if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Log.d(TAG, "Bluetooth device disconnected: " + device); + + disconnectBluetoothDevice(device); + } + } + }; + + private HIDDeviceManager(final Context context) { + mContext = context; + + HIDDeviceRegisterCallback(); + + mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE); + mIsChromebook = mContext.getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); + +// if (shouldClear) { +// SharedPreferences.Editor spedit = mSharedPreferences.edit(); +// spedit.clear(); +// spedit.commit(); +// } +// else + { + mNextDeviceId = mSharedPreferences.getInt("next_device_id", 0); + } + } + + Context getContext() { + return mContext; + } + + int getDeviceIDForIdentifier(String identifier) { + SharedPreferences.Editor spedit = mSharedPreferences.edit(); + + int result = mSharedPreferences.getInt(identifier, 0); + if (result == 0) { + result = mNextDeviceId++; + spedit.putInt("next_device_id", mNextDeviceId); + } + + spedit.putInt(identifier, result); + spedit.commit(); + return result; + } + + private void initializeUSB() { + mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE); + if (mUsbManager == null) { + return; + } + + /* + // Logging + for (UsbDevice device : mUsbManager.getDeviceList().values()) { + Log.i(TAG,"Path: " + device.getDeviceName()); + Log.i(TAG,"Manufacturer: " + device.getManufacturerName()); + Log.i(TAG,"Product: " + device.getProductName()); + Log.i(TAG,"ID: " + device.getDeviceId()); + Log.i(TAG,"Class: " + device.getDeviceClass()); + Log.i(TAG,"Protocol: " + device.getDeviceProtocol()); + Log.i(TAG,"Vendor ID " + device.getVendorId()); + Log.i(TAG,"Product ID: " + device.getProductId()); + Log.i(TAG,"Interface count: " + device.getInterfaceCount()); + Log.i(TAG,"---------------------------------------"); + + // Get interface details + for (int index = 0; index < device.getInterfaceCount(); index++) { + UsbInterface mUsbInterface = device.getInterface(index); + Log.i(TAG," ***** *****"); + Log.i(TAG," Interface index: " + index); + Log.i(TAG," Interface ID: " + mUsbInterface.getId()); + Log.i(TAG," Interface class: " + mUsbInterface.getInterfaceClass()); + Log.i(TAG," Interface subclass: " + mUsbInterface.getInterfaceSubclass()); + Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol()); + Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount()); + + // Get endpoint details + for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++) + { + UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi); + Log.i(TAG," ++++ ++++ ++++"); + Log.i(TAG," Endpoint index: " + epi); + Log.i(TAG," Attributes: " + mEndpoint.getAttributes()); + Log.i(TAG," Direction: " + mEndpoint.getDirection()); + Log.i(TAG," Number: " + mEndpoint.getEndpointNumber()); + Log.i(TAG," Interval: " + mEndpoint.getInterval()); + Log.i(TAG," Packet size: " + mEndpoint.getMaxPacketSize()); + Log.i(TAG," Type: " + mEndpoint.getType()); + } + } + } + Log.i(TAG," No more devices connected."); + */ + + // Register for USB broadcasts and permission completions + IntentFilter filter = new IntentFilter(); + filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + filter.addAction(HIDDeviceManager.ACTION_USB_PERMISSION); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver(mUsbBroadcast, filter, Context.RECEIVER_EXPORTED); + } else { + mContext.registerReceiver(mUsbBroadcast, filter); + } + + for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) { + handleUsbDeviceAttached(usbDevice); + } + } + + UsbManager getUSBManager() { + return mUsbManager; + } + + private void shutdownUSB() { + try { + mContext.unregisterReceiver(mUsbBroadcast); + } catch (Exception e) { + // We may not have registered, that's okay + } + } + + private boolean isHIDDeviceInterface(UsbDevice usbDevice, UsbInterface usbInterface) { + if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) { + return true; + } + if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) { + return true; + } + return false; + } + + private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) { + final int XB360_IFACE_SUBCLASS = 93; + final int XB360_IFACE_PROTOCOL = 1; // Wired + final int XB360W_IFACE_PROTOCOL = 129; // Wireless + final int[] SUPPORTED_VENDORS = { + 0x0079, // GPD Win 2 + 0x044f, // Thrustmaster + 0x045e, // Microsoft + 0x046d, // Logitech + 0x056e, // Elecom + 0x06a3, // Saitek + 0x0738, // Mad Catz + 0x07ff, // Mad Catz + 0x0e6f, // PDP + 0x0f0d, // Hori + 0x1038, // SteelSeries + 0x11c9, // Nacon + 0x12ab, // Unknown + 0x1430, // RedOctane + 0x146b, // BigBen + 0x1532, // Razer Sabertooth + 0x15e4, // Numark + 0x162e, // Joytech + 0x1689, // Razer Onza + 0x1949, // Lab126, Inc. + 0x1bad, // Harmonix + 0x20d6, // PowerA + 0x24c6, // PowerA + 0x2c22, // Qanba + 0x2dc8, // 8BitDo + 0x9886, // ASTRO Gaming + }; + + if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && + usbInterface.getInterfaceSubclass() == XB360_IFACE_SUBCLASS && + (usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL || + usbInterface.getInterfaceProtocol() == XB360W_IFACE_PROTOCOL)) { + int vendor_id = usbDevice.getVendorId(); + for (int supportedVid : SUPPORTED_VENDORS) { + if (vendor_id == supportedVid) { + return true; + } + } + } + return false; + } + + private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) { + final int XB1_IFACE_SUBCLASS = 71; + final int XB1_IFACE_PROTOCOL = 208; + final int[] SUPPORTED_VENDORS = { + 0x03f0, // HP + 0x044f, // Thrustmaster + 0x045e, // Microsoft + 0x0738, // Mad Catz + 0x0b05, // ASUS + 0x0e6f, // PDP + 0x0f0d, // Hori + 0x10f5, // Turtle Beach + 0x1532, // Razer Wildcat + 0x20d6, // PowerA + 0x24c6, // PowerA + 0x2dc8, // 8BitDo + 0x2e24, // Hyperkin + 0x3537, // GameSir + }; + + if (usbInterface.getId() == 0 && + usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && + usbInterface.getInterfaceSubclass() == XB1_IFACE_SUBCLASS && + usbInterface.getInterfaceProtocol() == XB1_IFACE_PROTOCOL) { + int vendor_id = usbDevice.getVendorId(); + for (int supportedVid : SUPPORTED_VENDORS) { + if (vendor_id == supportedVid) { + return true; + } + } + } + return false; + } + + private void handleUsbDeviceAttached(UsbDevice usbDevice) { + connectHIDDeviceUSB(usbDevice); + } + + private void handleUsbDeviceDetached(UsbDevice usbDevice) { + List devices = new ArrayList(); + for (HIDDevice device : mDevicesById.values()) { + if (usbDevice.equals(device.getDevice())) { + devices.add(device.getId()); + } + } + for (int id : devices) { + HIDDevice device = mDevicesById.get(id); + mDevicesById.remove(id); + device.shutdown(); + HIDDeviceDisconnected(id); + } + } + + private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) { + for (HIDDevice device : mDevicesById.values()) { + if (usbDevice.equals(device.getDevice())) { + boolean opened = false; + if (permission_granted) { + opened = device.open(); + } + HIDDeviceOpenResult(device.getId(), opened); + } + } + } + + private void connectHIDDeviceUSB(UsbDevice usbDevice) { + synchronized (this) { + int interface_mask = 0; + for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) { + UsbInterface usbInterface = usbDevice.getInterface(interface_index); + if (isHIDDeviceInterface(usbDevice, usbInterface)) { + // Check to see if we've already added this interface + // This happens with the Xbox Series X controller which has a duplicate interface 0, which is inactive + int interface_id = usbInterface.getId(); + if ((interface_mask & (1 << interface_id)) != 0) { + continue; + } + interface_mask |= (1 << interface_id); + + HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index); + int id = device.getId(); + mDevicesById.put(id, device); + HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol(), false); + } + } + } + } + + private void initializeBluetooth() { + Log.d(TAG, "Initializing Bluetooth"); + + if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ && + mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT"); + return; + } + + if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ && + mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH"); + return; + } + + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18 /* Android 4.3 (JELLY_BEAN_MR2) */)) { + Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE"); + return; + } + + // Find bonded bluetooth controllers and create SteamControllers for them + mBluetoothManager = (BluetoothManager)mContext.getSystemService(Context.BLUETOOTH_SERVICE); + if (mBluetoothManager == null) { + // This device doesn't support Bluetooth. + return; + } + + BluetoothAdapter btAdapter = mBluetoothManager.getAdapter(); + if (btAdapter == null) { + // This device has Bluetooth support in the codebase, but has no available adapters. + return; + } + + // Get our bonded devices. + for (BluetoothDevice device : btAdapter.getBondedDevices()) { + + Log.d(TAG, "Bluetooth device available: " + device); + if (isSteamController(device)) { + connectBluetoothDevice(device); + } + + } + + // NOTE: These don't work on Chromebooks, to my undying dismay. + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver(mBluetoothBroadcast, filter, Context.RECEIVER_EXPORTED); + } else { + mContext.registerReceiver(mBluetoothBroadcast, filter); + } + + if (mIsChromebook) { + mHandler = new Handler(Looper.getMainLooper()); + mLastBluetoothDevices = new ArrayList(); + + // final HIDDeviceManager finalThis = this; + // mHandler.postDelayed(new Runnable() { + // @Override + // public void run() { + // finalThis.chromebookConnectionHandler(); + // } + // }, 5000); + } + } + + private void shutdownBluetooth() { + try { + mContext.unregisterReceiver(mBluetoothBroadcast); + } catch (Exception e) { + // We may not have registered, that's okay + } + } + + // Chromebooks do not pass along ACTION_ACL_CONNECTED / ACTION_ACL_DISCONNECTED properly. + // This function provides a sort of dummy version of that, watching for changes in the + // connected devices and attempting to add controllers as things change. + void chromebookConnectionHandler() { + if (!mIsChromebook) { + return; + } + + ArrayList disconnected = new ArrayList(); + ArrayList connected = new ArrayList(); + + List currentConnected = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT); + + for (BluetoothDevice bluetoothDevice : currentConnected) { + if (!mLastBluetoothDevices.contains(bluetoothDevice)) { + connected.add(bluetoothDevice); + } + } + for (BluetoothDevice bluetoothDevice : mLastBluetoothDevices) { + if (!currentConnected.contains(bluetoothDevice)) { + disconnected.add(bluetoothDevice); + } + } + + mLastBluetoothDevices = currentConnected; + + for (BluetoothDevice bluetoothDevice : disconnected) { + disconnectBluetoothDevice(bluetoothDevice); + } + for (BluetoothDevice bluetoothDevice : connected) { + connectBluetoothDevice(bluetoothDevice); + } + + final HIDDeviceManager finalThis = this; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + finalThis.chromebookConnectionHandler(); + } + }, 10000); + } + + boolean connectBluetoothDevice(BluetoothDevice bluetoothDevice) { + Log.v(TAG, "connectBluetoothDevice device=" + bluetoothDevice); + synchronized (this) { + if (mBluetoothDevices.containsKey(bluetoothDevice)) { + Log.v(TAG, "Steam controller with address " + bluetoothDevice + " already exists, attempting reconnect"); + + HIDDeviceBLESteamController device = mBluetoothDevices.get(bluetoothDevice); + device.reconnect(); + + return false; + } + HIDDeviceBLESteamController device = new HIDDeviceBLESteamController(this, bluetoothDevice); + int id = device.getId(); + mBluetoothDevices.put(bluetoothDevice, device); + mDevicesById.put(id, device); + + // The Steam Controller will mark itself connected once initialization is complete + } + return true; + } + + void disconnectBluetoothDevice(BluetoothDevice bluetoothDevice) { + synchronized (this) { + HIDDeviceBLESteamController device = mBluetoothDevices.get(bluetoothDevice); + if (device == null) + return; + + int id = device.getId(); + mBluetoothDevices.remove(bluetoothDevice); + mDevicesById.remove(id); + device.shutdown(); + HIDDeviceDisconnected(id); + } + } + + boolean isSteamController(BluetoothDevice bluetoothDevice) { + // Sanity check. If you pass in a null device, by definition it is never a Steam Controller. + if (bluetoothDevice == null) { + return false; + } + + // If the device has no local name, we really don't want to try an equality check against it. + if (bluetoothDevice.getName() == null) { + return false; + } + + return bluetoothDevice.getName().equals("SteamController") && ((bluetoothDevice.getType() & BluetoothDevice.DEVICE_TYPE_LE) != 0); + } + + private void close() { + shutdownUSB(); + shutdownBluetooth(); + synchronized (this) { + for (HIDDevice device : mDevicesById.values()) { + device.shutdown(); + } + mDevicesById.clear(); + mBluetoothDevices.clear(); + HIDDeviceReleaseCallback(); + } + } + + public void setFrozen(boolean frozen) { + synchronized (this) { + for (HIDDevice device : mDevicesById.values()) { + device.setFrozen(frozen); + } + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + private HIDDevice getDevice(int id) { + synchronized (this) { + HIDDevice result = mDevicesById.get(id); + if (result == null) { + Log.v(TAG, "No device for id: " + id); + Log.v(TAG, "Available devices: " + mDevicesById.keySet()); + } + return result; + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////// JNI interface functions + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + boolean initialize(boolean usb, boolean bluetooth) { + Log.v(TAG, "initialize(" + usb + ", " + bluetooth + ")"); + + if (usb) { + initializeUSB(); + } + if (bluetooth) { + initializeBluetooth(); + } + return true; + } + + boolean openDevice(int deviceID) { + Log.v(TAG, "openDevice deviceID=" + deviceID); + HIDDevice device = getDevice(deviceID); + if (device == null) { + HIDDeviceDisconnected(deviceID); + return false; + } + + // Look to see if this is a USB device and we have permission to access it + UsbDevice usbDevice = device.getDevice(); + if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) { + HIDDeviceOpenPending(deviceID); + try { + final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31 + int flags; + if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) { + flags = FLAG_MUTABLE; + } else { + flags = 0; + } + if (Build.VERSION.SDK_INT >= 33 /* Android 14.0 (U) */) { + Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION); + intent.setPackage(mContext.getPackageName()); + mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags)); + } else { + mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags)); + } + } catch (Exception e) { + Log.v(TAG, "Couldn't request permission for USB device " + usbDevice); + HIDDeviceOpenResult(deviceID, false); + } + return false; + } + + try { + return device.open(); + } catch (Exception e) { + Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); + } + return false; + } + + int writeReport(int deviceID, byte[] report, boolean feature) { + try { + //Log.v(TAG, "writeReport deviceID=" + deviceID + " length=" + report.length); + HIDDevice device; + device = getDevice(deviceID); + if (device == null) { + HIDDeviceDisconnected(deviceID); + return -1; + } + + return device.writeReport(report, feature); + } catch (Exception e) { + Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); + } + return -1; + } + + boolean readReport(int deviceID, byte[] report, boolean feature) { + try { + //Log.v(TAG, "readReport deviceID=" + deviceID); + HIDDevice device; + device = getDevice(deviceID); + if (device == null) { + HIDDeviceDisconnected(deviceID); + return false; + } + + return device.readReport(report, feature); + } catch (Exception e) { + Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); + } + return false; + } + + void closeDevice(int deviceID) { + try { + Log.v(TAG, "closeDevice deviceID=" + deviceID); + HIDDevice device; + device = getDevice(deviceID); + if (device == null) { + HIDDeviceDisconnected(deviceID); + return; + } + + device.close(); + } catch (Exception e) { + Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); + } + } + + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////// Native methods + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + private native void HIDDeviceRegisterCallback(); + private native void HIDDeviceReleaseCallback(); + + native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number, int interface_class, int interface_subclass, int interface_protocol, boolean bBluetooth); + native void HIDDeviceOpenPending(int deviceID); + native void HIDDeviceOpenResult(int deviceID, boolean opened); + native void HIDDeviceDisconnected(int deviceID); + + native void HIDDeviceInputReport(int deviceID, byte[] report); + native void HIDDeviceReportResponse(int deviceID, byte[] report); +} diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java new file mode 100644 index 000000000..50dbb2204 --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java @@ -0,0 +1,318 @@ +package org.libsdl.app; + +import android.hardware.usb.*; +import android.os.Build; +import android.util.Log; +import java.util.Arrays; + +class HIDDeviceUSB implements HIDDevice { + + private static final String TAG = "hidapi"; + + protected HIDDeviceManager mManager; + protected UsbDevice mDevice; + protected int mInterfaceIndex; + protected int mInterface; + protected int mDeviceId; + protected UsbDeviceConnection mConnection; + protected UsbEndpoint mInputEndpoint; + protected UsbEndpoint mOutputEndpoint; + protected InputThread mInputThread; + protected boolean mRunning; + protected boolean mFrozen; + + public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) { + mManager = manager; + mDevice = usbDevice; + mInterfaceIndex = interface_index; + mInterface = mDevice.getInterface(mInterfaceIndex).getId(); + mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier()); + mRunning = false; + } + + String getIdentifier() { + return String.format("%s/%x/%x/%d", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId(), mInterfaceIndex); + } + + @Override + public int getId() { + return mDeviceId; + } + + @Override + public int getVendorId() { + return mDevice.getVendorId(); + } + + @Override + public int getProductId() { + return mDevice.getProductId(); + } + + @Override + public String getSerialNumber() { + String result = null; + if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) { + try { + result = mDevice.getSerialNumber(); + } + catch (SecurityException exception) { + //Log.w(TAG, "App permissions mean we cannot get serial number for device " + getDeviceName() + " message: " + exception.getMessage()); + } + } + if (result == null) { + result = ""; + } + return result; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public String getManufacturerName() { + String result = null; + if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) { + result = mDevice.getManufacturerName(); + } + if (result == null) { + result = String.format("%x", getVendorId()); + } + return result; + } + + @Override + public String getProductName() { + String result = null; + if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) { + result = mDevice.getProductName(); + } + if (result == null) { + result = String.format("%x", getProductId()); + } + return result; + } + + @Override + public UsbDevice getDevice() { + return mDevice; + } + + String getDeviceName() { + return getManufacturerName() + " " + getProductName() + "(0x" + String.format("%x", getVendorId()) + "/0x" + String.format("%x", getProductId()) + ")"; + } + + @Override + public boolean open() { + mConnection = mManager.getUSBManager().openDevice(mDevice); + if (mConnection == null) { + Log.w(TAG, "Unable to open USB device " + getDeviceName()); + return false; + } + + // Force claim our interface + UsbInterface iface = mDevice.getInterface(mInterfaceIndex); + if (!mConnection.claimInterface(iface, true)) { + Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName()); + close(); + return false; + } + + // Find the endpoints + for (int j = 0; j < iface.getEndpointCount(); j++) { + UsbEndpoint endpt = iface.getEndpoint(j); + switch (endpt.getDirection()) { + case UsbConstants.USB_DIR_IN: + if (mInputEndpoint == null) { + mInputEndpoint = endpt; + } + break; + case UsbConstants.USB_DIR_OUT: + if (mOutputEndpoint == null) { + mOutputEndpoint = endpt; + } + break; + } + } + + // Make sure the required endpoints were present + if (mInputEndpoint == null || mOutputEndpoint == null) { + Log.w(TAG, "Missing required endpoint on USB device " + getDeviceName()); + close(); + return false; + } + + // Start listening for input + mRunning = true; + mInputThread = new InputThread(); + mInputThread.start(); + + return true; + } + + @Override + public int writeReport(byte[] report, boolean feature) { + if (mConnection == null) { + Log.w(TAG, "writeReport() called with no device connection"); + return -1; + } + + if (feature) { + int res = -1; + int offset = 0; + int length = report.length; + boolean skipped_report_id = false; + byte report_number = report[0]; + + if (report_number == 0x0) { + ++offset; + --length; + skipped_report_id = true; + } + + res = mConnection.controlTransfer( + UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT, + 0x09/*HID set_report*/, + (3/*HID feature*/ << 8) | report_number, + mInterface, + report, offset, length, + 1000/*timeout millis*/); + + if (res < 0) { + Log.w(TAG, "writeFeatureReport() returned " + res + " on device " + getDeviceName()); + return -1; + } + + if (skipped_report_id) { + ++length; + } + return length; + } else { + int res = mConnection.bulkTransfer(mOutputEndpoint, report, report.length, 1000); + if (res != report.length) { + Log.w(TAG, "writeOutputReport() returned " + res + " on device " + getDeviceName()); + } + return res; + } + } + + @Override + public boolean readReport(byte[] report, boolean feature) { + int res = -1; + int offset = 0; + int length = report.length; + boolean skipped_report_id = false; + byte report_number = report[0]; + + if (mConnection == null) { + Log.w(TAG, "readReport() called with no device connection"); + return false; + } + + if (report_number == 0x0) { + /* Offset the return buffer by 1, so that the report ID + will remain in byte 0. */ + ++offset; + --length; + skipped_report_id = true; + } + + res = mConnection.controlTransfer( + UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_IN, + 0x01/*HID get_report*/, + ((feature ? 3/*HID feature*/ : 1/*HID Input*/) << 8) | report_number, + mInterface, + report, offset, length, + 1000/*timeout millis*/); + + if (res < 0) { + Log.w(TAG, "getFeatureReport() returned " + res + " on device " + getDeviceName()); + return false; + } + + if (skipped_report_id) { + ++res; + ++length; + } + + byte[] data; + if (res == length) { + data = report; + } else { + data = Arrays.copyOfRange(report, 0, res); + } + mManager.HIDDeviceReportResponse(mDeviceId, data); + + return true; + } + + @Override + public void close() { + mRunning = false; + if (mInputThread != null) { + while (mInputThread.isAlive()) { + mInputThread.interrupt(); + try { + mInputThread.join(); + } catch (InterruptedException e) { + // Keep trying until we're done + } + } + mInputThread = null; + } + if (mConnection != null) { + UsbInterface iface = mDevice.getInterface(mInterfaceIndex); + mConnection.releaseInterface(iface); + mConnection.close(); + mConnection = null; + } + } + + @Override + public void shutdown() { + close(); + mManager = null; + } + + @Override + public void setFrozen(boolean frozen) { + mFrozen = frozen; + } + + protected class InputThread extends Thread { + @Override + public void run() { + int packetSize = mInputEndpoint.getMaxPacketSize(); + byte[] packet = new byte[packetSize]; + while (mRunning) { + int r; + try + { + r = mConnection.bulkTransfer(mInputEndpoint, packet, packetSize, 1000); + } + catch (Exception e) + { + Log.v(TAG, "Exception in UsbDeviceConnection bulktransfer: " + e); + break; + } + if (r < 0) { + // Could be a timeout or an I/O error + } + if (r > 0) { + byte[] data; + if (r == packetSize) { + data = packet; + } else { + data = Arrays.copyOfRange(packet, 0, r); + } + + if (!mFrozen) { + mManager.HIDDeviceInputReport(mDeviceId, data); + } + } + } + } + } +} diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDL.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDL.java new file mode 100644 index 000000000..d5d3d69ae --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDL.java @@ -0,0 +1,90 @@ +package org.libsdl.app; + +import android.content.Context; + +import java.lang.Class; +import java.lang.reflect.Method; + +/** + SDL library initialization +*/ +public class SDL { + + // This function should be called first and sets up the native code + // so it can call into the Java classes + static public void setupJNI() { + SDLActivity.nativeSetupJNI(); + SDLAudioManager.nativeSetupJNI(); + SDLControllerManager.nativeSetupJNI(); + } + + // This function should be called each time the activity is started + static public void initialize() { + setContext(null); + + SDLActivity.initialize(); + SDLAudioManager.initialize(); + SDLControllerManager.initialize(); + } + + // This function stores the current activity (SDL or not) + static public void setContext(Context context) { + SDLAudioManager.setContext(context); + mContext = context; + } + + static public Context getContext() { + return mContext; + } + + static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException { + loadLibrary(libraryName, mContext); + } + + static void loadLibrary(String libraryName, Context context) throws UnsatisfiedLinkError, SecurityException, NullPointerException { + + if (libraryName == null) { + throw new NullPointerException("No library name provided."); + } + + try { + // Let's see if we have ReLinker available in the project. This is necessary for + // some projects that have huge numbers of local libraries bundled, and thus may + // trip a bug in Android's native library loader which ReLinker works around. (If + // loadLibrary works properly, ReLinker will simply use the normal Android method + // internally.) + // + // To use ReLinker, just add it as a dependency. For more information, see + // https://github.com/KeepSafe/ReLinker for ReLinker's repository. + // + Class relinkClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker"); + Class relinkListenerClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener"); + Class contextClass = context.getClassLoader().loadClass("android.content.Context"); + Class stringClass = context.getClassLoader().loadClass("java.lang.String"); + + // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if + // they've changed during updates. + Method forceMethod = relinkClass.getDeclaredMethod("force"); + Object relinkInstance = forceMethod.invoke(null); + Class relinkInstanceClass = relinkInstance.getClass(); + + // Actually load the library! + Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass); + loadMethod.invoke(relinkInstance, context, libraryName, null, null); + } + catch (final Throwable e) { + // Fall back + try { + System.loadLibrary(libraryName); + } + catch (final UnsatisfiedLinkError ule) { + throw ule; + } + catch (final SecurityException se) { + throw se; + } + } + } + + protected static Context mContext; +} diff --git a/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLActivity.java b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLActivity.java new file mode 100644 index 000000000..85d51541c --- /dev/null +++ b/examples/android/SDL_GPU/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -0,0 +1,2189 @@ +package org.libsdl.app; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.UiModeManager; +import android.content.ActivityNotFoundException; +import android.content.ClipboardManager; +import android.content.ClipData; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.hardware.Sensor; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.SparseArray; +import android.view.Display; +import android.view.Gravity; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.PointerIcon; +import android.view.Surface; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.webkit.MimeTypeMap; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Locale; + + +/** + SDL Activity +*/ +public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener { + private static final String TAG = "SDL"; + private static final int SDL_MAJOR_VERSION = 3; + private static final int SDL_MINOR_VERSION = 3; + private static final int SDL_MICRO_VERSION = 0; +/* + // Display InputType.SOURCE/CLASS of events and devices + // + // SDLActivity.debugSource(device.getSources(), "device[" + device.getName() + "]"); + // SDLActivity.debugSource(event.getSource(), "event"); + public static void debugSource(int sources, String prefix) { + int s = sources; + int s_copy = sources; + String cls = ""; + String src = ""; + int tst = 0; + int FLAG_TAINTED = 0x80000000; + + if ((s & InputDevice.SOURCE_CLASS_BUTTON) != 0) cls += " BUTTON"; + if ((s & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) cls += " JOYSTICK"; + if ((s & InputDevice.SOURCE_CLASS_POINTER) != 0) cls += " POINTER"; + if ((s & InputDevice.SOURCE_CLASS_POSITION) != 0) cls += " POSITION"; + if ((s & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) cls += " TRACKBALL"; + + + int s2 = s_copy & ~InputDevice.SOURCE_ANY; // keep class bits + s2 &= ~( InputDevice.SOURCE_CLASS_BUTTON + | InputDevice.SOURCE_CLASS_JOYSTICK + | InputDevice.SOURCE_CLASS_POINTER + | InputDevice.SOURCE_CLASS_POSITION + | InputDevice.SOURCE_CLASS_TRACKBALL); + + if (s2 != 0) cls += "Some_Unknown"; + + s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class; + + if (Build.VERSION.SDK_INT >= 23) { + tst = InputDevice.SOURCE_BLUETOOTH_STYLUS; + if ((s & tst) == tst) src += " BLUETOOTH_STYLUS"; + s2 &= ~tst; + } + + tst = InputDevice.SOURCE_DPAD; + if ((s & tst) == tst) src += " DPAD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_GAMEPAD; + if ((s & tst) == tst) src += " GAMEPAD"; + s2 &= ~tst; + + if (Build.VERSION.SDK_INT >= 21) { + tst = InputDevice.SOURCE_HDMI; + if ((s & tst) == tst) src += " HDMI"; + s2 &= ~tst; + } + + tst = InputDevice.SOURCE_JOYSTICK; + if ((s & tst) == tst) src += " JOYSTICK"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_KEYBOARD; + if ((s & tst) == tst) src += " KEYBOARD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_MOUSE; + if ((s & tst) == tst) src += " MOUSE"; + s2 &= ~tst; + + if (Build.VERSION.SDK_INT >= 26) { + tst = InputDevice.SOURCE_MOUSE_RELATIVE; + if ((s & tst) == tst) src += " MOUSE_RELATIVE"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_ROTARY_ENCODER; + if ((s & tst) == tst) src += " ROTARY_ENCODER"; + s2 &= ~tst; + } + tst = InputDevice.SOURCE_STYLUS; + if ((s & tst) == tst) src += " STYLUS"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TOUCHPAD; + if ((s & tst) == tst) src += " TOUCHPAD"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_TOUCHSCREEN; + if ((s & tst) == tst) src += " TOUCHSCREEN"; + s2 &= ~tst; + + if (Build.VERSION.SDK_INT >= 18) { + tst = InputDevice.SOURCE_TOUCH_NAVIGATION; + if ((s & tst) == tst) src += " TOUCH_NAVIGATION"; + s2 &= ~tst; + } + + tst = InputDevice.SOURCE_TRACKBALL; + if ((s & tst) == tst) src += " TRACKBALL"; + s2 &= ~tst; + + tst = InputDevice.SOURCE_ANY; + if ((s & tst) == tst) src += " ANY"; + s2 &= ~tst; + + if (s == FLAG_TAINTED) src += " FLAG_TAINTED"; + s2 &= ~FLAG_TAINTED; + + if (s2 != 0) src += " Some_Unknown"; + + Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src); + } +*/ + + public static boolean mIsResumedCalled, mHasFocus; + public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */); + + // Cursor types + // private static final int SDL_SYSTEM_CURSOR_NONE = -1; + private static final int SDL_SYSTEM_CURSOR_ARROW = 0; + private static final int SDL_SYSTEM_CURSOR_IBEAM = 1; + private static final int SDL_SYSTEM_CURSOR_WAIT = 2; + private static final int SDL_SYSTEM_CURSOR_CROSSHAIR = 3; + private static final int SDL_SYSTEM_CURSOR_WAITARROW = 4; + private static final int SDL_SYSTEM_CURSOR_SIZENWSE = 5; + private static final int SDL_SYSTEM_CURSOR_SIZENESW = 6; + private static final int SDL_SYSTEM_CURSOR_SIZEWE = 7; + private static final int SDL_SYSTEM_CURSOR_SIZENS = 8; + private static final int SDL_SYSTEM_CURSOR_SIZEALL = 9; + private static final int SDL_SYSTEM_CURSOR_NO = 10; + private static final int SDL_SYSTEM_CURSOR_HAND = 11; + private static final int SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT = 12; + private static final int SDL_SYSTEM_CURSOR_WINDOW_TOP = 13; + private static final int SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT = 14; + private static final int SDL_SYSTEM_CURSOR_WINDOW_RIGHT = 15; + private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT = 16; + private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOM = 17; + private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT = 18; + private static final int SDL_SYSTEM_CURSOR_WINDOW_LEFT = 19; + + protected static final int SDL_ORIENTATION_UNKNOWN = 0; + protected static final int SDL_ORIENTATION_LANDSCAPE = 1; + protected static final int SDL_ORIENTATION_LANDSCAPE_FLIPPED = 2; + protected static final int SDL_ORIENTATION_PORTRAIT = 3; + protected static final int SDL_ORIENTATION_PORTRAIT_FLIPPED = 4; + + protected static int mCurrentRotation; + protected static Locale mCurrentLocale; + + // Handle the state of the native layer + public enum NativeState { + INIT, RESUMED, PAUSED + } + + public static NativeState mNextNativeState; + public static NativeState mCurrentNativeState; + + /** If shared libraries (e.g. SDL or the native application) could not be loaded. */ + public static boolean mBrokenLibraries = true; + + // Main components + protected static SDLActivity mSingleton; + protected static SDLSurface mSurface; + protected static SDLDummyEdit mTextEdit; + protected static boolean mScreenKeyboardShown; + protected static ViewGroup mLayout; + protected static SDLClipboardHandler mClipboardHandler; + protected static Hashtable mCursors; + protected static int mLastCursorID; + protected static SDLGenericMotionListener_API14 mMotionListener; + protected static HIDDeviceManager mHIDDeviceManager; + + // This is what SDL runs in. It invokes SDL_main(), eventually + protected static Thread mSDLThread; + protected static boolean mSDLMainFinished = false; + protected static boolean mActivityCreated = false; + private static SDLFileDialogState mFileDialogState = null; + protected static boolean mDispatchingKeyEvent = false; + + protected static SDLGenericMotionListener_API14 getMotionListener() { + if (mMotionListener == null) { + if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) { + mMotionListener = new SDLGenericMotionListener_API26(); + } else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { + mMotionListener = new SDLGenericMotionListener_API24(); + } else { + mMotionListener = new SDLGenericMotionListener_API14(); + } + } + + return mMotionListener; + } + + /** + * The application entry point, called on a dedicated thread (SDLThread). + * The default implementation uses the getMainSharedObject() and getMainFunction() methods + * to invoke native code from the specified shared library. + * It can be overridden by derived classes. + */ + protected void main() { + String library = SDLActivity.mSingleton.getMainSharedObject(); + String function = SDLActivity.mSingleton.getMainFunction(); + String[] arguments = SDLActivity.mSingleton.getArguments(); + + Log.v("SDL", "Running main function " + function + " from library " + library); + SDLActivity.nativeRunMain(library, function, arguments); + Log.v("SDL", "Finished main function"); + } + + /** + * This method returns the name of the shared object with the application entry point + * It can be overridden by derived classes. + */ + protected String getMainSharedObject() { + String library; + String[] libraries = SDLActivity.mSingleton.getLibraries(); + if (libraries.length > 0) { + library = "lib" + libraries[libraries.length - 1] + ".so"; + } else { + library = "libmain.so"; + } + return getContext().getApplicationInfo().nativeLibraryDir + "/" + library; + } + + /** + * This method returns the name of the application entry point + * It can be overridden by derived classes. + */ + protected String getMainFunction() { + return "SDL_main"; + } + + /** + * This method is called by SDL before loading the native shared libraries. + * It can be overridden to provide names of shared libraries to be loaded. + * The default implementation returns the defaults. It never returns null. + * An array returned by a new implementation must at least contain "SDL3". + * Also keep in mind that the order the libraries are loaded may matter. + * @return names of shared libraries to be loaded (e.g. "SDL3", "main"). + */ + protected String[] getLibraries() { + return new String[] { + "SDL3", + // "SDL3_image", + // "SDL3_mixer", + // "SDL3_net", + // "SDL3_ttf", + "main" + }; + } + + // Load the .so + public void loadLibraries() { + for (String lib : getLibraries()) { + SDL.loadLibrary(lib, this); + } + } + + /** + * This method is called by SDL before starting the native application thread. + * It can be overridden to provide the arguments after the application name. + * The default implementation returns an empty array. It never returns null. + * @return arguments for the native application. + */ + protected String[] getArguments() { + return new String[0]; + } + + public static void initialize() { + // The static nature of the singleton and Android quirkyness force us to initialize everything here + // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values + mSingleton = null; + mSurface = null; + mTextEdit = null; + mLayout = null; + mClipboardHandler = null; + mCursors = new Hashtable(); + mLastCursorID = 0; + mSDLThread = null; + mIsResumedCalled = false; + mHasFocus = true; + mNextNativeState = NativeState.INIT; + mCurrentNativeState = NativeState.INIT; + } + + protected SDLSurface createSDLSurface(Context context) { + return new SDLSurface(context); + } + + // Setup + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.v(TAG, "Manufacturer: " + Build.MANUFACTURER); + Log.v(TAG, "Device: " + Build.DEVICE); + Log.v(TAG, "Model: " + Build.MODEL); + Log.v(TAG, "onCreate()"); + super.onCreate(savedInstanceState); + + + /* Control activity re-creation */ + if (mSDLMainFinished || mActivityCreated) { + boolean allow_recreate = SDLActivity.nativeAllowRecreateActivity(); + if (mSDLMainFinished) { + Log.v(TAG, "SDL main() finished"); + } + if (allow_recreate) { + Log.v(TAG, "activity re-created"); + } else { + Log.v(TAG, "activity finished"); + System.exit(0); + return; + } + } + + mActivityCreated = true; + + try { + Thread.currentThread().setName("SDLActivity"); + } catch (Exception e) { + Log.v(TAG, "modify thread properties failed " + e.toString()); + } + + // Load shared libraries + String errorMsgBrokenLib = ""; + try { + loadLibraries(); + mBrokenLibraries = false; /* success */ + } catch(UnsatisfiedLinkError e) { + System.err.println(e.getMessage()); + mBrokenLibraries = true; + errorMsgBrokenLib = e.getMessage(); + } catch(Exception e) { + System.err.println(e.getMessage()); + mBrokenLibraries = true; + errorMsgBrokenLib = e.getMessage(); + } + + if (!mBrokenLibraries) { + String expected_version = String.valueOf(SDL_MAJOR_VERSION) + "." + + String.valueOf(SDL_MINOR_VERSION) + "." + + String.valueOf(SDL_MICRO_VERSION); + String version = nativeGetVersion(); + if (!version.equals(expected_version)) { + mBrokenLibraries = true; + errorMsgBrokenLib = "SDL C/Java version mismatch (expected " + expected_version + ", got " + version + ")"; + } + } + + if (mBrokenLibraries) { + mSingleton = this; + AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); + dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall." + + System.getProperty("line.separator") + + System.getProperty("line.separator") + + "Error: " + errorMsgBrokenLib); + dlgAlert.setTitle("SDL Error"); + dlgAlert.setPositiveButton("Exit", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog,int id) { + // if this button is clicked, close current activity + SDLActivity.mSingleton.finish(); + } + }); + dlgAlert.setCancelable(false); + dlgAlert.create().show(); + + return; + } + + + /* Control activity re-creation */ + /* Robustness: check that the native code is run for the first time. + * (Maybe Activity was reset, but not the native code.) */ + { + int run_count = SDLActivity.nativeCheckSDLThreadCounter(); /* get and increment a native counter */ + if (run_count != 0) { + boolean allow_recreate = SDLActivity.nativeAllowRecreateActivity(); + if (allow_recreate) { + Log.v(TAG, "activity re-created // run_count: " + run_count); + } else { + Log.v(TAG, "activity finished // run_count: " + run_count); + System.exit(0); + return; + } + } + } + + // Set up JNI + SDL.setupJNI(); + + // Initialize state + SDL.initialize(); + + // So we can call stuff from static callbacks + mSingleton = this; + SDL.setContext(this); + + mClipboardHandler = new SDLClipboardHandler(); + + mHIDDeviceManager = HIDDeviceManager.acquire(this); + + // Set up the surface + mSurface = createSDLSurface(this); + + mLayout = new RelativeLayout(this); + mLayout.addView(mSurface); + + // Get our current screen orientation and pass it down. + SDLActivity.nativeSetNaturalOrientation(SDLActivity.getNaturalOrientation()); + mCurrentRotation = SDLActivity.getCurrentRotation(); + SDLActivity.onNativeRotationChanged(mCurrentRotation); + + try { + if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) { + mCurrentLocale = getContext().getResources().getConfiguration().locale; + } else { + mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0); + } + } catch(Exception ignored) { + } + + switch (getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) { + case Configuration.UI_MODE_NIGHT_NO: + SDLActivity.onNativeDarkModeChanged(false); + break; + case Configuration.UI_MODE_NIGHT_YES: + SDLActivity.onNativeDarkModeChanged(true); + break; + } + + setContentView(mLayout); + + setWindowStyle(false); + + getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this); + + // Get filename from "Open with" of another application + Intent intent = getIntent(); + if (intent != null && intent.getData() != null) { + String filename = intent.getData().getPath(); + if (filename != null) { + Log.v(TAG, "Got filename: " + filename); + SDLActivity.onNativeDropFile(filename); + } + } + } + + protected void pauseNativeThread() { + mNextNativeState = NativeState.PAUSED; + mIsResumedCalled = false; + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.handleNativeState(); + } + + protected void resumeNativeThread() { + mNextNativeState = NativeState.RESUMED; + mIsResumedCalled = true; + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.handleNativeState(); + } + + // Events + @Override + protected void onPause() { + Log.v(TAG, "onPause()"); + super.onPause(); + + if (mHIDDeviceManager != null) { + mHIDDeviceManager.setFrozen(true); + } + if (!mHasMultiWindow) { + pauseNativeThread(); + } + } + + @Override + protected void onResume() { + Log.v(TAG, "onResume()"); + super.onResume(); + + if (mHIDDeviceManager != null) { + mHIDDeviceManager.setFrozen(false); + } + if (!mHasMultiWindow) { + resumeNativeThread(); + } + } + + @Override + protected void onStop() { + Log.v(TAG, "onStop()"); + super.onStop(); + if (mHasMultiWindow) { + pauseNativeThread(); + } + } + + @Override + protected void onStart() { + Log.v(TAG, "onStart()"); + super.onStart(); + if (mHasMultiWindow) { + resumeNativeThread(); + } + } + + public static int getNaturalOrientation() { + int result = SDL_ORIENTATION_UNKNOWN; + + Activity activity = (Activity)getContext(); + if (activity != null) { + Configuration config = activity.getResources().getConfiguration(); + Display display = activity.getWindowManager().getDefaultDisplay(); + int rotation = display.getRotation(); + if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && + config.orientation == Configuration.ORIENTATION_LANDSCAPE) || + ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && + config.orientation == Configuration.ORIENTATION_PORTRAIT)) { + result = SDL_ORIENTATION_LANDSCAPE; + } else { + result = SDL_ORIENTATION_PORTRAIT; + } + } + return result; + } + + public static int getCurrentRotation() { + int result = 0; + + Activity activity = (Activity)getContext(); + if (activity != null) { + Display display = activity.getWindowManager().getDefaultDisplay(); + switch (display.getRotation()) { + case Surface.ROTATION_0: + result = 0; + break; + case Surface.ROTATION_90: + result = 90; + break; + case Surface.ROTATION_180: + result = 180; + break; + case Surface.ROTATION_270: + result = 270; + break; + } + } + return result; + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + Log.v(TAG, "onWindowFocusChanged(): " + hasFocus); + + if (SDLActivity.mBrokenLibraries) { + return; + } + + mHasFocus = hasFocus; + if (hasFocus) { + mNextNativeState = NativeState.RESUMED; + SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded(); + + SDLActivity.handleNativeState(); + nativeFocusChanged(true); + + } else { + nativeFocusChanged(false); + if (!mHasMultiWindow) { + mNextNativeState = NativeState.PAUSED; + SDLActivity.handleNativeState(); + } + } + } + + @Override + public void onTrimMemory(int level) { + Log.v(TAG, "onTrimMemory()"); + super.onTrimMemory(level); + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.nativeLowMemory(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + Log.v(TAG, "onConfigurationChanged()"); + super.onConfigurationChanged(newConfig); + + if (SDLActivity.mBrokenLibraries) { + return; + } + + if (mCurrentLocale == null || !mCurrentLocale.equals(newConfig.locale)) { + mCurrentLocale = newConfig.locale; + SDLActivity.onNativeLocaleChanged(); + } + + switch (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) { + case Configuration.UI_MODE_NIGHT_NO: + SDLActivity.onNativeDarkModeChanged(false); + break; + case Configuration.UI_MODE_NIGHT_YES: + SDLActivity.onNativeDarkModeChanged(true); + break; + } + } + + @Override + protected void onDestroy() { + Log.v(TAG, "onDestroy()"); + + if (mHIDDeviceManager != null) { + HIDDeviceManager.release(mHIDDeviceManager); + mHIDDeviceManager = null; + } + + SDLAudioManager.release(this); + + if (SDLActivity.mBrokenLibraries) { + super.onDestroy(); + return; + } + + if (SDLActivity.mSDLThread != null) { + + // Send Quit event to "SDLThread" thread + SDLActivity.nativeSendQuit(); + + // Wait for "SDLThread" thread to end + try { + // Use a timeout because: + // C SDLmain() thread might have started (mSDLThread.start() called) + // while the SDL_Init() might not have been called yet, + // and so the previous QUIT event will be discarded by SDL_Init() and app is running, not exiting. + SDLActivity.mSDLThread.join(1000); + } catch(Exception e) { + Log.v(TAG, "Problem stopping SDLThread: " + e); + } + } + + SDLActivity.nativeQuit(); + + super.onDestroy(); + } + + @Override + public void onBackPressed() { + // Check if we want to block the back button in case of mouse right click. + // + // If we do, the normal hardware back button will no longer work and people have to use home, + // but the mouse right click will work. + // + boolean trapBack = SDLActivity.nativeGetHintBoolean("SDL_ANDROID_TRAP_BACK_BUTTON", false); + if (trapBack) { + // Exit and let the mouse handler handle this button (if appropriate) + return; + } + + // Default system back button behavior. + if (!isFinishing()) { + super.onBackPressed(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (mFileDialogState != null && mFileDialogState.requestCode == requestCode) { + /* This is our file dialog */ + String[] filelist = null; + + if (data != null) { + Uri singleFileUri = data.getData(); + + if (singleFileUri == null) { + /* Use Intent.getClipData to get multiple choices */ + ClipData clipData = data.getClipData(); + assert clipData != null; + + filelist = new String[clipData.getItemCount()]; + + for (int i = 0; i < filelist.length; i++) { + String uri = clipData.getItemAt(i).getUri().toString(); + filelist[i] = uri; + } + } else { + /* Only one file is selected. */ + filelist = new String[]{singleFileUri.toString()}; + } + } else { + /* User cancelled the request. */ + filelist = new String[0]; + } + + // TODO: Detect the file MIME type and pass the filter value accordingly. + SDLActivity.onNativeFileDialog(requestCode, filelist, -1); + mFileDialogState = null; + } + } + + // Called by JNI from SDL. + public static void manualBackButton() { + mSingleton.pressBackButton(); + } + + // Used to get us onto the activity's main thread + public void pressBackButton() { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (!SDLActivity.this.isFinishing()) { + SDLActivity.this.superOnBackPressed(); + } + } + }); + } + + // Used to access the system back behavior. + public void superOnBackPressed() { + super.onBackPressed(); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + + if (SDLActivity.mBrokenLibraries) { + return false; + } + + int keyCode = event.getKeyCode(); + // Ignore certain special keys so they're handled by Android + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || + keyCode == KeyEvent.KEYCODE_VOLUME_UP || + keyCode == KeyEvent.KEYCODE_CAMERA || + keyCode == KeyEvent.KEYCODE_ZOOM_IN || /* API 11 */ + keyCode == KeyEvent.KEYCODE_ZOOM_OUT /* API 11 */ + ) { + return false; + } + mDispatchingKeyEvent = true; + boolean result = super.dispatchKeyEvent(event); + mDispatchingKeyEvent = false; + return result; + } + + public static boolean dispatchingKeyEvent() { + return mDispatchingKeyEvent; + } + + /* Transition to next state */ + public static void handleNativeState() { + + if (mNextNativeState == mCurrentNativeState) { + // Already in same state, discard. + return; + } + + // Try a transition to init state + if (mNextNativeState == NativeState.INIT) { + + mCurrentNativeState = mNextNativeState; + return; + } + + // Try a transition to paused state + if (mNextNativeState == NativeState.PAUSED) { + if (mSDLThread != null) { + nativePause(); + } + if (mSurface != null) { + mSurface.handlePause(); + } + mCurrentNativeState = mNextNativeState; + return; + } + + // Try a transition to resumed state + if (mNextNativeState == NativeState.RESUMED) { + if (mSurface.mIsSurfaceReady && (mHasFocus || mHasMultiWindow) && mIsResumedCalled) { + if (mSDLThread == null) { + // This is the entry point to the C app. + // Start up the C app thread and enable sensor input for the first time + // FIXME: Why aren't we enabling sensor input at start? + + mSDLThread = new Thread(new SDLMain(), "SDLThread"); + mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true); + mSDLThread.start(); + + // No nativeResume(), don't signal Android_ResumeSem + } else { + nativeResume(); + } + mSurface.handleResume(); + + mCurrentNativeState = mNextNativeState; + } + } + } + + // Messages from the SDLMain thread + protected static final int COMMAND_CHANGE_TITLE = 1; + protected static final int COMMAND_CHANGE_WINDOW_STYLE = 2; + protected static final int COMMAND_TEXTEDIT_HIDE = 3; + protected static final int COMMAND_SET_KEEP_SCREEN_ON = 5; + protected static final int COMMAND_USER = 0x8000; + + protected static boolean mFullscreenModeActive; + + /** + * This method is called by SDL if SDL did not handle a message itself. + * This happens if a received message contains an unsupported command. + * Method can be overwritten to handle Messages in a different class. + * @param command the command of the message. + * @param param the parameter of the message. May be null. + * @return if the message was handled in overridden method. + */ + protected boolean onUnhandledMessage(int command, Object param) { + return false; + } + + /** + * A Handler class for Messages from native SDL applications. + * It uses current Activities as target (e.g. for the title). + * static to prevent implicit references to enclosing object. + */ + protected static class SDLCommandHandler extends Handler { + @Override + public void handleMessage(Message msg) { + Context context = SDL.getContext(); + if (context == null) { + Log.e(TAG, "error handling message, getContext() returned null"); + return; + } + switch (msg.arg1) { + case COMMAND_CHANGE_TITLE: + if (context instanceof Activity) { + ((Activity) context).setTitle((String)msg.obj); + } else { + Log.e(TAG, "error handling message, getContext() returned no Activity"); + } + break; + case COMMAND_CHANGE_WINDOW_STYLE: + if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) { + if (context instanceof Activity) { + Window window = ((Activity) context).getWindow(); + if (window != null) { + if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) { + int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE; + window.getDecorView().setSystemUiVisibility(flags); + window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + SDLActivity.mFullscreenModeActive = true; + } else { + int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE; + window.getDecorView().setSystemUiVisibility(flags); + window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + SDLActivity.mFullscreenModeActive = false; + } + if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) { + window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + } + if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */ && + Build.VERSION.SDK_INT < 35 /* Android 15 */) { + SDLActivity.onNativeInsetsChanged(0, 0, 0, 0); + } + } + } else { + Log.e(TAG, "error handling message, getContext() returned no Activity"); + } + } + break; + case COMMAND_TEXTEDIT_HIDE: + if (mTextEdit != null) { + // Note: On some devices setting view to GONE creates a flicker in landscape. + // Setting the View's sizes to 0 is similar to GONE but without the flicker. + // The sizes will be set to useful values when the keyboard is shown again. + mTextEdit.setLayoutParams(new RelativeLayout.LayoutParams(0, 0)); + + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); + + mScreenKeyboardShown = false; + + mSurface.requestFocus(); + } + break; + case COMMAND_SET_KEEP_SCREEN_ON: + { + if (context instanceof Activity) { + Window window = ((Activity) context).getWindow(); + if (window != null) { + if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + } + break; + } + default: + if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { + Log.e(TAG, "error handling message, command is " + msg.arg1); + } + } + } + } + + // Handler for the messages + Handler commandHandler = new SDLCommandHandler(); + + // Send a message from the SDLMain thread + protected boolean sendCommand(int command, Object data) { + Message msg = commandHandler.obtainMessage(); + msg.arg1 = command; + msg.obj = data; + boolean result = commandHandler.sendMessage(msg); + + if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) { + if (command == COMMAND_CHANGE_WINDOW_STYLE) { + // Ensure we don't return until the resize has actually happened, + // or 500ms have passed. + + boolean bShouldWait = false; + + if (data instanceof Integer) { + // Let's figure out if we're already laid out fullscreen or not. + Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + DisplayMetrics realMetrics = new DisplayMetrics(); + display.getRealMetrics(realMetrics); + + boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) && + (realMetrics.heightPixels == mSurface.getHeight())); + + if ((Integer) data == 1) { + // If we aren't laid out fullscreen or actively in fullscreen mode already, we're going + // to change size and should wait for surfaceChanged() before we return, so the size + // is right back in native code. If we're already laid out fullscreen, though, we're + // not going to change size even if we change decor modes, so we shouldn't wait for + // surfaceChanged() -- which may not even happen -- and should return immediately. + bShouldWait = !bFullscreenLayout; + } else { + // If we're laid out fullscreen (even if the status bar and nav bar are present), + // or are actively in fullscreen, we're going to change size and should wait for + // surfaceChanged before we return, so the size is right back in native code. + bShouldWait = bFullscreenLayout; + } + } + + if (bShouldWait && (SDLActivity.getContext() != null)) { + // We'll wait for the surfaceChanged() method, which will notify us + // when called. That way, we know our current size is really the + // size we need, instead of grabbing a size that's still got + // the navigation and/or status bars before they're hidden. + // + // We'll wait for up to half a second, because some devices + // take a surprisingly long time for the surface resize, but + // then we'll just give up and return. + // + synchronized (SDLActivity.getContext()) { + try { + SDLActivity.getContext().wait(500); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + } + } + + return result; + } + + // C functions we call + public static native String nativeGetVersion(); + public static native int nativeSetupJNI(); + public static native void nativeInitMainThread(); + public static native void nativeCleanupMainThread(); + public static native int nativeRunMain(String library, String function, Object arguments); + public static native void nativeLowMemory(); + public static native void nativeSendQuit(); + public static native void nativeQuit(); + public static native void nativePause(); + public static native void nativeResume(); + public static native void nativeFocusChanged(boolean hasFocus); + public static native void onNativeDropFile(String filename); + public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate); + public static native void onNativeResize(); + public static native void onNativeKeyDown(int keycode); + public static native void onNativeKeyUp(int keycode); + public static native boolean onNativeSoftReturnKey(); + public static native void onNativeKeyboardFocusLost(); + public static native void onNativeMouse(int button, int action, float x, float y, boolean relative); + public static native void onNativeTouch(int touchDevId, int pointerFingerId, + int action, float x, + float y, float p); + public static native void onNativePen(int penId, int button, int action, float x, float y, float p); + public static native void onNativeAccel(float x, float y, float z); + public static native void onNativeClipboardChanged(); + public static native void onNativeSurfaceCreated(); + public static native void onNativeSurfaceChanged(); + public static native void onNativeSurfaceDestroyed(); + public static native String nativeGetHint(String name); + public static native boolean nativeGetHintBoolean(String name, boolean default_value); + public static native void nativeSetenv(String name, String value); + public static native void nativeSetNaturalOrientation(int orientation); + public static native void onNativeRotationChanged(int rotation); + public static native void onNativeInsetsChanged(int left, int right, int top, int bottom); + public static native void nativeAddTouch(int touchId, String name); + public static native void nativePermissionResult(int requestCode, boolean result); + public static native void onNativeLocaleChanged(); + public static native void onNativeDarkModeChanged(boolean enabled); + public static native boolean nativeAllowRecreateActivity(); + public static native int nativeCheckSDLThreadCounter(); + public static native void onNativeFileDialog(int requestCode, String[] filelist, int filter); + + /** + * This method is called by SDL using JNI. + */ + public static boolean setActivityTitle(String title) { + // Called from SDLMain() thread and can't directly affect the view + return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); + } + + /** + * This method is called by SDL using JNI. + */ + public static void setWindowStyle(boolean fullscreen) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.sendCommand(COMMAND_CHANGE_WINDOW_STYLE, fullscreen ? 1 : 0); + } + + /** + * This method is called by SDL using JNI. + * This is a static method for JNI convenience, it calls a non-static method + * so that is can be overridden + */ + public static void setOrientation(int w, int h, boolean resizable, String hint) + { + if (mSingleton != null) { + mSingleton.setOrientationBis(w, h, resizable, hint); + } + } + + /** + * This can be overridden + */ + public void setOrientationBis(int w, int h, boolean resizable, String hint) + { + int orientation_landscape = -1; + int orientation_portrait = -1; + + /* If set, hint "explicitly controls which UI orientations are allowed". */ + if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) { + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE; + } else if (hint.contains("LandscapeLeft")) { + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + } else if (hint.contains("LandscapeRight")) { + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + } + + /* exact match to 'Portrait' to distinguish with PortraitUpsideDown */ + boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait"); + + if (contains_Portrait && hint.contains("PortraitUpsideDown")) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT; + } else if (contains_Portrait) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + } else if (hint.contains("PortraitUpsideDown")) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + } + + boolean is_landscape_allowed = (orientation_landscape != -1); + boolean is_portrait_allowed = (orientation_portrait != -1); + int req; /* Requested orientation */ + + /* No valid hint, nothing is explicitly allowed */ + if (!is_portrait_allowed && !is_landscape_allowed) { + if (resizable) { + /* All orientations are allowed, respecting user orientation lock setting */ + req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER; + } else { + /* Fixed window and nothing specified. Get orientation from w/h of created window */ + req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); + } + } else { + /* At least one orientation is allowed */ + if (resizable) { + if (is_portrait_allowed && is_landscape_allowed) { + /* hint allows both landscape and portrait, promote to full user */ + req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER; + } else { + /* Use the only one allowed "orientation" */ + req = (is_landscape_allowed ? orientation_landscape : orientation_portrait); + } + } else { + /* Fixed window and both orientations are allowed. Choose one. */ + if (is_portrait_allowed && is_landscape_allowed) { + req = (w > h ? orientation_landscape : orientation_portrait); + } else { + /* Use the only one allowed "orientation" */ + req = (is_landscape_allowed ? orientation_landscape : orientation_portrait); + } + } + } + + Log.v(TAG, "setOrientation() requestedOrientation=" + req + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint); + mSingleton.setRequestedOrientation(req); + } + + /** + * This method is called by SDL using JNI. + */ + public static void minimizeWindow() { + + if (mSingleton == null) { + return; + } + + Intent startMain = new Intent(Intent.ACTION_MAIN); + startMain.addCategory(Intent.CATEGORY_HOME); + startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mSingleton.startActivity(startMain); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean shouldMinimizeOnFocusLoss() { + return false; + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isScreenKeyboardShown() + { + if (mTextEdit == null) { + return false; + } + + if (!mScreenKeyboardShown) { + return false; + } + + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + return imm.isAcceptingText(); + + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean supportsRelativeMouse() + { + // DeX mode in Samsung Experience 9.0 and earlier doesn't support relative mice properly under + // Android 7 APIs, and simply returns no data under Android 8 APIs. + // + // This is fixed in Samsung Experience 9.5, which corresponds to Android 8.1.0, and + // thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result, + // we should stick to relative mode. + // + if (Build.VERSION.SDK_INT < 27 /* Android 8.1 (O_MR1) */ && isDeXMode()) { + return false; + } + + return SDLActivity.getMotionListener().supportsRelativeMouse(); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean setRelativeMouseEnabled(boolean enabled) + { + if (enabled && !supportsRelativeMouse()) { + return false; + } + + return SDLActivity.getMotionListener().setRelativeMouseEnabled(enabled); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean sendMessage(int command, int param) { + if (mSingleton == null) { + return false; + } + return mSingleton.sendCommand(command, param); + } + + /** + * This method is called by SDL using JNI. + */ + public static Context getContext() { + return SDL.getContext(); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isAndroidTV() { + UiModeManager uiModeManager = (UiModeManager) getContext().getSystemService(UI_MODE_SERVICE); + if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) { + return true; + } + if (Build.MANUFACTURER.equals("MINIX") && Build.MODEL.equals("NEO-U1")) { + return true; + } + if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) { + return true; + } + if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV")) { + return true; + } + return false; + } + + public static boolean isVRHeadset() { + if (Build.MANUFACTURER.equals("Oculus") && Build.MODEL.startsWith("Quest")) { + return true; + } + if (Build.MANUFACTURER.equals("Pico")) { + return true; + } + return false; + } + + public static double getDiagonal() + { + DisplayMetrics metrics = new DisplayMetrics(); + Activity activity = (Activity)getContext(); + if (activity == null) { + return 0.0; + } + activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + + double dWidthInches = metrics.widthPixels / (double)metrics.xdpi; + double dHeightInches = metrics.heightPixels / (double)metrics.ydpi; + + return Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches)); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isTablet() { + // If our diagonal size is seven inches or greater, we consider ourselves a tablet. + return (getDiagonal() >= 7.0); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isChromebook() { + if (getContext() == null) { + return false; + } + return getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isDeXMode() { + if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) { + return false; + } + try { + final Configuration config = getContext().getResources().getConfiguration(); + final Class configClass = config.getClass(); + return configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass) + == configClass.getField("semDesktopModeEnabled").getInt(config); + } catch(Exception ignored) { + return false; + } + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean getManifestEnvironmentVariables() { + try { + if (getContext() == null) { + return false; + } + + ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = applicationInfo.metaData; + if (bundle == null) { + return false; + } + String prefix = "SDL_ENV."; + final int trimLength = prefix.length(); + for (String key : bundle.keySet()) { + if (key.startsWith(prefix)) { + String name = key.substring(trimLength); + String value = bundle.get(key).toString(); + nativeSetenv(name, value); + } + } + /* environment variables set! */ + return true; + } catch (Exception e) { + Log.v(TAG, "exception " + e.toString()); + } + return false; + } + + // This method is called by SDLControllerManager's API 26 Generic Motion Handler. + public static View getContentView() { + return mLayout; + } + + static class ShowTextInputTask implements Runnable { + /* + * This is used to regulate the pan&scan method to have some offset from + * the bottom edge of the input region and the top edge of an input + * method (soft keyboard) + */ + static final int HEIGHT_PADDING = 15; + + public int input_type; + public int x, y, w, h; + + public ShowTextInputTask(int input_type, int x, int y, int w, int h) { + this.input_type = input_type; + this.x = x; + this.y = y; + this.w = w; + this.h = h; + + /* Minimum size of 1 pixel, so it takes focus. */ + if (this.w <= 0) { + this.w = 1; + } + if (this.h + HEIGHT_PADDING <= 0) { + this.h = 1 - HEIGHT_PADDING; + } + } + + @Override + public void run() { + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING); + params.leftMargin = x; + params.topMargin = y; + + if (mTextEdit == null) { + mTextEdit = new SDLDummyEdit(SDL.getContext()); + + mLayout.addView(mTextEdit, params); + } else { + mTextEdit.setLayoutParams(params); + } + mTextEdit.setInputType(input_type); + + mTextEdit.setVisibility(View.VISIBLE); + mTextEdit.requestFocus(); + + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mTextEdit, 0); + + mScreenKeyboardShown = true; + } + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean showTextInput(int input_type, int x, int y, int w, int h) { + // Transfer the task to the main thread as a Runnable + return mSingleton.commandHandler.post(new ShowTextInputTask(input_type, x, y, w, h)); + } + + public static boolean isTextInputEvent(KeyEvent event) { + + // Key pressed with Ctrl should be sent as SDL_KEYDOWN/SDL_KEYUP and not SDL_TEXTINPUT + if (event.isCtrlPressed()) { + return false; + } + + return event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE; + } + + public static boolean handleKeyEvent(View v, int keyCode, KeyEvent event, InputConnection ic) { + int deviceId = event.getDeviceId(); + int source = event.getSource(); + + if (source == InputDevice.SOURCE_UNKNOWN) { + InputDevice device = InputDevice.getDevice(deviceId); + if (device != null) { + source = device.getSources(); + } + } + +// if (event.getAction() == KeyEvent.ACTION_DOWN) { +// Log.v("SDL", "key down: " + keyCode + ", deviceId = " + deviceId + ", source = " + source); +// } else if (event.getAction() == KeyEvent.ACTION_UP) { +// Log.v("SDL", "key up: " + keyCode + ", deviceId = " + deviceId + ", source = " + source); +// } + + // Dispatch the different events depending on where they come from + // Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD + // So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD + // + // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and + // SOURCE_JOYSTICK, while its key events arrive from the keyboard source + // So, retrieve the device itself and check all of its sources + if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) { + // Note that we process events with specific key codes here + if (event.getAction() == KeyEvent.ACTION_DOWN) { + if (SDLControllerManager.onNativePadDown(deviceId, keyCode)) { + return true; + } + } else if (event.getAction() == KeyEvent.ACTION_UP) { + if (SDLControllerManager.onNativePadUp(deviceId, keyCode)) { + return true; + } + } + } + + if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) { + if (SDLActivity.isVRHeadset()) { + // The Oculus Quest controller back button comes in as source mouse, so accept that + } else { + // on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses + // they are ignored here because sending them as mouse input to SDL is messy + if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) { + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + case KeyEvent.ACTION_UP: + // mark the event as handled or it will be handled by system + // handling KEYCODE_BACK by system will call onBackPressed() + return true; + } + } + } + } + + if (event.getAction() == KeyEvent.ACTION_DOWN) { + onNativeKeyDown(keyCode); + + if (isTextInputEvent(event)) { + if (ic != null) { + ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1); + } else { + SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1); + } + } + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + onNativeKeyUp(keyCode); + return true; + } + + return false; + } + + /** + * This method is called by SDL using JNI. + */ + public static Surface getNativeSurface() { + if (SDLActivity.mSurface == null) { + return null; + } + return SDLActivity.mSurface.getNativeSurface(); + } + + // Input + + /** + * This method is called by SDL using JNI. + */ + public static void initTouch() { + int[] ids = InputDevice.getDeviceIds(); + + for (int id : ids) { + InputDevice device = InputDevice.getDevice(id); + /* Allow SOURCE_TOUCHSCREEN and also Virtual InputDevices because they can send TOUCHSCREEN events */ + if (device != null && ((device.getSources() & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN + || device.isVirtual())) { + + nativeAddTouch(device.getId(), device.getName()); + } + } + } + + // Messagebox + + /** Result of current messagebox. Also used for blocking the calling thread. */ + protected final int[] messageboxSelection = new int[1]; + + /** + * This method is called by SDL using JNI. + * Shows the messagebox from UI thread and block calling thread. + * buttonFlags, buttonIds and buttonTexts must have same length. + * @param buttonFlags array containing flags for every button. + * @param buttonIds array containing id for every button. + * @param buttonTexts array containing text for every button. + * @param colors null for default or array of length 5 containing colors. + * @return button id or -1. + */ + public int messageboxShowMessageBox( + final int flags, + final String title, + final String message, + final int[] buttonFlags, + final int[] buttonIds, + final String[] buttonTexts, + final int[] colors) { + + messageboxSelection[0] = -1; + + // sanity checks + + if ((buttonFlags.length != buttonIds.length) && (buttonIds.length != buttonTexts.length)) { + return -1; // implementation broken + } + + // collect arguments for Dialog + + final Bundle args = new Bundle(); + args.putInt("flags", flags); + args.putString("title", title); + args.putString("message", message); + args.putIntArray("buttonFlags", buttonFlags); + args.putIntArray("buttonIds", buttonIds); + args.putStringArray("buttonTexts", buttonTexts); + args.putIntArray("colors", colors); + + // trigger Dialog creation on UI thread + + runOnUiThread(new Runnable() { + @Override + public void run() { + messageboxCreateAndShow(args); + } + }); + + // block the calling thread + + synchronized (messageboxSelection) { + try { + messageboxSelection.wait(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + return -1; + } + } + + // return selected value + + return messageboxSelection[0]; + } + + protected void messageboxCreateAndShow(Bundle args) { + + // TODO set values from "flags" to messagebox dialog + + // get colors + + int[] colors = args.getIntArray("colors"); + int backgroundColor; + int textColor; + int buttonBorderColor; + int buttonBackgroundColor; + int buttonSelectedColor; + if (colors != null) { + int i = -1; + backgroundColor = colors[++i]; + textColor = colors[++i]; + buttonBorderColor = colors[++i]; + buttonBackgroundColor = colors[++i]; + buttonSelectedColor = colors[++i]; + } else { + backgroundColor = Color.TRANSPARENT; + textColor = Color.TRANSPARENT; + buttonBorderColor = Color.TRANSPARENT; + buttonBackgroundColor = Color.TRANSPARENT; + buttonSelectedColor = Color.TRANSPARENT; + } + + // create dialog with title and a listener to wake up calling thread + + final AlertDialog dialog = new AlertDialog.Builder(this).create(); + dialog.setTitle(args.getString("title")); + dialog.setCancelable(false); + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface unused) { + synchronized (messageboxSelection) { + messageboxSelection.notify(); + } + } + }); + + // create text + + TextView message = new TextView(this); + message.setGravity(Gravity.CENTER); + message.setText(args.getString("message")); + if (textColor != Color.TRANSPARENT) { + message.setTextColor(textColor); + } + + // create buttons + + int[] buttonFlags = args.getIntArray("buttonFlags"); + int[] buttonIds = args.getIntArray("buttonIds"); + String[] buttonTexts = args.getStringArray("buttonTexts"); + + final SparseArray