From 8e2e577e2ff29f3f9a0ecad85f982ffb7fddf9cd Mon Sep 17 00:00:00 2001 From: Lich Date: Sun, 18 Feb 2024 17:08:53 +0900 Subject: [PATCH] Add support for window close button calback (#1697) --- core/platform/GLViewImpl.cpp | 20 +++++++ core/platform/GLViewImpl.h | 3 + .../Source/WindowTest/WindowTest.cpp | 58 +++++++++++++++++++ .../cpp-tests/Source/WindowTest/WindowTest.h | 14 +++++ 4 files changed, 95 insertions(+) diff --git a/core/platform/GLViewImpl.cpp b/core/platform/GLViewImpl.cpp index 79ca3a29bc..9e9fc7c3a8 100644 --- a/core/platform/GLViewImpl.cpp +++ b/core/platform/GLViewImpl.cpp @@ -173,6 +173,14 @@ public: } } + static void onGLFWWindowCloseCallback(GLFWwindow* window) + { + if (_view) + { + _view->onGLFWWindowCloseCallback(window); + } + } + private: static GLViewImpl* _view; }; @@ -182,6 +190,7 @@ const std::string GLViewImpl::EVENT_WINDOW_POSITIONED = "glview_window_positione const std::string GLViewImpl::EVENT_WINDOW_RESIZED = "glview_window_resized"; const std::string GLViewImpl::EVENT_WINDOW_FOCUSED = "glview_window_focused"; const std::string GLViewImpl::EVENT_WINDOW_UNFOCUSED = "glview_window_unfocused"; +const std::string GLViewImpl::EVENT_WINDOW_CLOSE = "glview_window_close"; //////////////////////////////////////////////////// @@ -575,6 +584,7 @@ bool GLViewImpl::initWithRect(std::string_view viewName, const ax::Rect& rect, f glfwSetWindowSizeCallback(_mainWindow, GLFWEventHandler::onGLFWWindowSizeCallback); glfwSetWindowIconifyCallback(_mainWindow, GLFWEventHandler::onGLFWWindowIconifyCallback); glfwSetWindowFocusCallback(_mainWindow, GLFWEventHandler::onGLFWWindowFocusCallback); + glfwSetWindowCloseCallback(_mainWindow, GLFWEventHandler::onGLFWWindowCloseCallback); #if (AX_TARGET_PLATFORM != AX_PLATFORM_MAC) loadGL(); @@ -1282,6 +1292,16 @@ void GLViewImpl::onGLFWWindowFocusCallback(GLFWwindow* /*window*/, int focused) } } +void GLViewImpl::onGLFWWindowCloseCallback(GLFWwindow* window) +{ + bool isClose = true; + Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(GLViewImpl::EVENT_WINDOW_CLOSE, &isClose); + if (isClose == false) + { + glfwSetWindowShouldClose(window, 0); + } +} + #if (AX_TARGET_PLATFORM != AX_PLATFORM_MAC) static bool loadFboExtensions() { diff --git a/core/platform/GLViewImpl.h b/core/platform/GLViewImpl.h index fd4e7385a5..c7a3a437a1 100644 --- a/core/platform/GLViewImpl.h +++ b/core/platform/GLViewImpl.h @@ -2,6 +2,7 @@ Copyright (c) 2010-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). https://axmolengine.github.io/ @@ -171,6 +172,7 @@ protected: void onGLFWWindowSizeCallback(GLFWwindow* window, int width, int height); void onGLFWWindowIconifyCallback(GLFWwindow* window, int iconified); void onGLFWWindowFocusCallback(GLFWwindow* window, int focused); + void onGLFWWindowCloseCallback(GLFWwindow* window); bool _isTouchDevice = false; bool _captured; @@ -200,6 +202,7 @@ public: static const std::string EVENT_WINDOW_RESIZED; static const std::string EVENT_WINDOW_FOCUSED; static const std::string EVENT_WINDOW_UNFOCUSED; + static const std::string EVENT_WINDOW_CLOSE; private: AX_DISALLOW_COPY_AND_ASSIGN(GLViewImpl); diff --git a/tests/cpp-tests/Source/WindowTest/WindowTest.cpp b/tests/cpp-tests/Source/WindowTest/WindowTest.cpp index 502047025b..fc38d4ac56 100644 --- a/tests/cpp-tests/Source/WindowTest/WindowTest.cpp +++ b/tests/cpp-tests/Source/WindowTest/WindowTest.cpp @@ -36,6 +36,7 @@ WindowTests::WindowTests() ADD_TEST_CASE(WindowTestFullscreen2); ADD_TEST_CASE(WindowTestFullscreen3); ADD_TEST_CASE(WindowTestResizedAndPositioned); + ADD_TEST_CASE(WindowTestClose); } std::string WindowTest::title() const @@ -165,4 +166,61 @@ void WindowTestResizedAndPositioned::onWindowResized(EventCustom* e) label2->setString(StringUtils::format("size : %d, %d", (int)size->width, (int)size->height)); } +void WindowTestClose::onEnter() +{ + WindowTest::onEnter(); + + label = nullptr; + + _director->getEventDispatcher()->addCustomEventListener(GLViewImpl::EVENT_WINDOW_CLOSE, + AX_CALLBACK_1(WindowTestClose::onWindowClose, this)); +} + +void WindowTestClose::onExit() +{ + WindowTest::onExit(); + _director->getEventDispatcher()->removeCustomEventListeners(GLViewImpl::EVENT_WINDOW_CLOSE); +} + +std::string WindowTestClose::subtitle() const +{ + return "Window close callback test"; +} + +void WindowTestClose::onWindowClose(EventCustom* e) +{ + auto isClose = static_cast(e->getUserData()); + if (isClose == nullptr) + return; + + // false prevents the window from closing + *isClose = false; + + this->stopActionByTag(1); + if (label != nullptr) + { + label->removeFromParent(); + label = nullptr; + } + + auto s = _director->getWinSize(); + label = Label::createWithTTF(StringUtils::format("Window close button callback!"), "fonts/Marker Felt.ttf", 16.0f); + label->setPosition(s.width / 2, s.height / 2); + addChild(label); + + auto delay = DelayTime::create(3.0); + auto callFunc = CallFunc::create( + [this]() + { + if (label != nullptr) + { + label->removeFromParent(); + label = nullptr; + } + }); + auto sequence = Sequence::create(delay, callFunc, nullptr); + sequence->setTag(1); + this->runAction(sequence); +} + #endif diff --git a/tests/cpp-tests/Source/WindowTest/WindowTest.h b/tests/cpp-tests/Source/WindowTest/WindowTest.h index b6bf24fd6b..c1ba4a50eb 100644 --- a/tests/cpp-tests/Source/WindowTest/WindowTest.h +++ b/tests/cpp-tests/Source/WindowTest/WindowTest.h @@ -92,6 +92,20 @@ private: ax::Label* label2; }; +class WindowTestClose : public WindowTest +{ +public: + CREATE_FUNC(WindowTestClose); + virtual void onEnter() override; + virtual void onExit() override; + virtual std::string subtitle() const override; + + void onWindowClose(ax::EventCustom* e); + +private: + ax::Label* label; +}; + #endif /* __WINDOWTEST_H__ */ #endif