From 3ec0f4bea19b8fc718cb8d48125f92007765afe3 Mon Sep 17 00:00:00 2001 From: Filipe Lemos Date: Sat, 20 Oct 2018 19:10:09 +0100 Subject: [PATCH 1/2] Add `GLView::setCursor` for desktop platforms --- cocos/platform/CCGLView.h | 15 +++++++- .../platform/desktop/CCGLViewImpl-desktop.cpp | 34 +++++++++++++++++-- cocos/platform/desktop/CCGLViewImpl-desktop.h | 20 +++++++++-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/cocos/platform/CCGLView.h b/cocos/platform/CCGLView.h index 5752ad4ba3ff..8ebba52ebf27 100644 --- a/cocos/platform/CCGLView.h +++ b/cocos/platform/CCGLView.h @@ -195,6 +195,19 @@ class CC_DLL GLView : public Ref */ virtual float getFrameZoomFactor() const { return 1.0; } + /** + * Sets the cursor for the window with custom image. + * + * @param filename A path to image file, e.g., "cursors/custom.png". + * @param hotspot Cursor hotspot, as a anchor point, default is top left (0, 1) + */ + virtual void setCursor(const std::string& filename, Vec2 hotspot = Vec2::ANCHOR_TOP_LEFT) {} + + /** + * Sets the cursor for the window back to default. + */ + virtual void setDefaultCursor() {} + /** * Hide or Show the mouse cursor if there is one. * @@ -363,7 +376,7 @@ class CC_DLL GLView : public Ref /** Set window icon (implemented for windows and linux). * - * @param filename A path to image file, e.g., "icons/cusom.png". + * @param filename A path to image file, e.g., "icons/custom.png". */ virtual void setIcon(const std::string& filename) const {}; diff --git a/cocos/platform/desktop/CCGLViewImpl-desktop.cpp b/cocos/platform/desktop/CCGLViewImpl-desktop.cpp index b16cf473746b..f5860937e3e3 100644 --- a/cocos/platform/desktop/CCGLViewImpl-desktop.cpp +++ b/cocos/platform/desktop/CCGLViewImpl-desktop.cpp @@ -39,9 +39,7 @@ THE SOFTWARE. #include "base/ccUtils.h" #include "base/ccUTF8.h" #include "2d/CCCamera.h" -#if CC_ICON_SET_SUPPORT #include "platform/CCImage.h" -#endif /* CC_ICON_SET_SUPPORT */ NS_CC_BEGIN @@ -207,6 +205,7 @@ GLViewImpl::GLViewImpl(bool initglfw) , _monitor(nullptr) , _mouseX(0.0f) , _mouseY(0.0f) +, _cursor(nullptr) { _viewName = "cocos2dx"; g_keyCodeMap.clear(); @@ -504,6 +503,37 @@ void GLViewImpl::setDefaultIcon() const { } #endif /* CC_ICON_SET_SUPPORT */ +void GLViewImpl::setCursor(const std::string& filename, Vec2 hotspot) { + + if (_cursor) { + glfwDestroyCursor(_cursor); + _cursor = nullptr; + } + + Image* ccImage = new (std::nothrow) Image(); + if (ccImage && ccImage->initWithImageFile(filename)) { + GLFWimage image; + image.width = ccImage->getWidth(); + image.height = ccImage->getHeight(); + image.pixels = ccImage->getData(); + _cursor = glfwCreateCursor(&image, (int)(hotspot.x * image.width), (int)((1.0f - hotspot.y) * image.height)); + if (_cursor) { + glfwSetCursor(_mainWindow, _cursor); + } + } + CC_SAFE_DELETE(ccImage); +} + +void GLViewImpl::setDefaultCursor() { + + if (_cursor) { + glfwDestroyCursor(_cursor); + _cursor = nullptr; + } + + glfwSetCursor(_mainWindow, NULL); +} + void GLViewImpl::setCursorVisible( bool isVisible ) { if( _mainWindow == NULL ) diff --git a/cocos/platform/desktop/CCGLViewImpl-desktop.h b/cocos/platform/desktop/CCGLViewImpl-desktop.h index 6b493ff8dc57..219ef7dff1a6 100644 --- a/cocos/platform/desktop/CCGLViewImpl-desktop.h +++ b/cocos/platform/desktop/CCGLViewImpl-desktop.h @@ -102,14 +102,26 @@ class CC_DLL GLViewImpl : public GLView virtual void setDefaultIcon() const override; #endif /* CC_ICON_SET_SUPPORT */ - /* - * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop. + /** + * Sets the cursor for the window with custom image. */ - void setFrameZoomFactor(float zoomFactor) override; + virtual void setCursor(const std::string& filename, Vec2 hotspot = Vec2::ANCHOR_TOP_LEFT) override; + + /** + * Sets the cursor for the window back to default. + */ + virtual void setDefaultCursor() override; + /** * Hide or Show the mouse cursor if there is one. */ virtual void setCursorVisible(bool isVisible) override; + + /* + * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop. + */ + void setFrameZoomFactor(float zoomFactor) override; + /** Retina support is disabled by default * @note This method is only available on Mac. */ @@ -169,6 +181,8 @@ class CC_DLL GLViewImpl : public GLView float _mouseX; float _mouseY; + GLFWcursor* _cursor; + friend class GLFWEventHandler; public: From af5738b60f7d2fc7e42d92f59fb95dd1c4080274 Mon Sep 17 00:00:00 2001 From: Filipe Lemos Date: Sun, 4 Nov 2018 21:51:06 +0000 Subject: [PATCH 2/2] Add test for custom mouse cursor --- build/cocos2d_tests.xcodeproj/project.pbxproj | 8 ++++ .../cpp-tests/Classes/InputTest/MouseTest.cpp | 44 ++++++++++++++++++ tests/cpp-tests/Classes/InputTest/MouseTest.h | 15 ++++++ .../cpp-tests/Resources/InputTest/cursor1.png | Bin 0 -> 760 bytes .../cpp-tests/Resources/InputTest/cursor2.png | Bin 0 -> 233 bytes 5 files changed, 67 insertions(+) create mode 100644 tests/cpp-tests/Resources/InputTest/cursor1.png create mode 100644 tests/cpp-tests/Resources/InputTest/cursor2.png diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj b/build/cocos2d_tests.xcodeproj/project.pbxproj index c3fb3dd9da83..307567abd40a 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj @@ -1129,6 +1129,9 @@ 52B47A341A534B2B004E4C60 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B47A331A534B2B004E4C60 /* Security.framework */; }; 52B47A351A53A43A004E4C60 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B47A331A534B2B004E4C60 /* Security.framework */; }; 53367D561DC22891005862DE /* WindowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53367D541DC22891005862DE /* WindowTest.cpp */; }; + 53E6A008218FA06E002BE515 /* InputTest in Resources */ = {isa = PBXBuildFile; fileRef = 53E6A007218FA06D002BE515 /* InputTest */; }; + 53E6A009218FA06E002BE515 /* InputTest in Resources */ = {isa = PBXBuildFile; fileRef = 53E6A007218FA06D002BE515 /* InputTest */; }; + 53E6A00A218FA06E002BE515 /* InputTest in Resources */ = {isa = PBXBuildFile; fileRef = 53E6A007218FA06D002BE515 /* InputTest */; }; 59620E8F1921E5CF002021B6 /* Bug-Child.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59620E8D1921E5CF002021B6 /* Bug-Child.cpp */; }; 59620E901921E5CF002021B6 /* Bug-Child.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59620E8D1921E5CF002021B6 /* Bug-Child.cpp */; }; 59E170151AB42EB10007F2BF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 826294421AAF071500CB7CF7 /* Security.framework */; }; @@ -2302,6 +2305,7 @@ 52B47A331A534B2B004E4C60 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 53367D541DC22891005862DE /* WindowTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowTest.cpp; sourceTree = ""; }; 53367D551DC22891005862DE /* WindowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowTest.h; sourceTree = ""; }; + 53E6A007218FA06D002BE515 /* InputTest */ = {isa = PBXFileReference; lastKnownFileType = folder; name = InputTest; path = "../tests/cpp-tests/Resources/InputTest"; sourceTree = ""; }; 59620E8D1921E5CF002021B6 /* Bug-Child.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "Bug-Child.cpp"; sourceTree = ""; }; 59620E8E1921E5CF002021B6 /* Bug-Child.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Bug-Child.h"; sourceTree = ""; }; 5EBEECAE1995247000429821 /* DrawNode3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DrawNode3D.cpp; path = Sprite3DTest/DrawNode3D.cpp; sourceTree = ""; }; @@ -3976,6 +3980,7 @@ 1AC35CBC18CED84500F37B72 /* hd */, 1AC35CBD18CED84500F37B72 /* Hello.png */, 1AC35CBE18CED84500F37B72 /* Images */, + 53E6A007218FA06D002BE515 /* InputTest */, 15B3709219EE5D1000ABE682 /* Manifests */, 5046AB5A1AF2C4180060550B /* Materials */, 1AC35CC118CED84500F37B72 /* Misc */, @@ -5699,6 +5704,7 @@ 5046AB5B1AF2C4180060550B /* Materials in Resources */, B63993311A49359F00B07923 /* Particle3D in Resources */, 1AC35CEC18CED84500F37B72 /* fonts in Resources */, + 53E6A008218FA06E002BE515 /* InputTest in Resources */, 460629781CDB4DBA00B44058 /* ccs-res in Resources */, 1AC35CCA18CED84500F37B72 /* animations in Resources */, 1AC35CEA18CED84500F37B72 /* fileLookup.plist in Resources */, @@ -5776,6 +5782,7 @@ 507B41211C31BEA60067B53E /* animations in Resources */, 507B41221C31BEA60067B53E /* cocosvideo.mp4 in Resources */, 507B41231C31BEA60067B53E /* Sprite3DTest in Resources */, + 53E6A00A218FA06E002BE515 /* InputTest in Resources */, 507B41251C31BEA60067B53E /* hd in Resources */, 507B41271C31BEA60067B53E /* Misc in Resources */, 507B41281C31BEA60067B53E /* Hello.png in Resources */, @@ -5949,6 +5956,7 @@ 1AC35CE918CED84500F37B72 /* extensions in Resources */, 3E2BDAD219BEA3E20055CDCD /* audio in Resources */, 5046AB5C1AF2C4180060550B /* Materials in Resources */, + 53E6A009218FA06E002BE515 /* InputTest in Resources */, C08689C318D370C90093E810 /* background.caf in Resources */, 15B3709419EE5D1000ABE682 /* Manifests in Resources */, 1AC35D0B18CED84500F37B72 /* zwoptex in Resources */, diff --git a/tests/cpp-tests/Classes/InputTest/MouseTest.cpp b/tests/cpp-tests/Classes/InputTest/MouseTest.cpp index c810030515bd..eebe58113603 100644 --- a/tests/cpp-tests/Classes/InputTest/MouseTest.cpp +++ b/tests/cpp-tests/Classes/InputTest/MouseTest.cpp @@ -32,6 +32,7 @@ MouseTests::MouseTests() { ADD_TEST_CASE(MouseEventTest); ADD_TEST_CASE(HideMouseTest); + ADD_TEST_CASE(CursorTest); } //------------------------------------------------------------------ @@ -146,3 +147,46 @@ std::string HideMouseTest::subtitle() const return "Click to hide mouse"; } +//------------------------------------------------------------------ +// +// CursorTest +// +//------------------------------------------------------------------ + +CursorTest::CursorTest() +{ + _cursor = 0; + _lis = EventListenerMouse::create(); + _lis->onMouseDown = [this](Event* e){ + _cursor = (_cursor + 1) % 3; + switch (_cursor) { + case 1: + Director::getInstance()->getOpenGLView()->setCursor("InputTest/cursor1.png"); + break; + case 2: + Director::getInstance()->getOpenGLView()->setCursor("InputTest/cursor2.png", Point::ANCHOR_MIDDLE); + break; + default: + Director::getInstance()->getOpenGLView()->setDefaultCursor(); + break; + } + }; + + _eventDispatcher->addEventListenerWithSceneGraphPriority(_lis, this); +} + +CursorTest::~CursorTest() +{ + _eventDispatcher->removeEventListener(_lis); +} + +std::string CursorTest::title() const +{ + return "Custom Mouse Cursor"; +} + +std::string CursorTest::subtitle() const +{ + return "Click to change cursor"; +} + diff --git a/tests/cpp-tests/Classes/InputTest/MouseTest.h b/tests/cpp-tests/Classes/InputTest/MouseTest.h index cc2162dad881..73e191f94539 100644 --- a/tests/cpp-tests/Classes/InputTest/MouseTest.h +++ b/tests/cpp-tests/Classes/InputTest/MouseTest.h @@ -71,4 +71,19 @@ class HideMouseTest : public BaseMouseTest cocos2d::EventListenerMouse* _lis; }; +class CursorTest : public BaseMouseTest +{ +public: + CREATE_FUNC(CursorTest); + CursorTest(); + ~CursorTest(); + + virtual std::string title() const override; + virtual std::string subtitle() const override; + +private: + int _cursor; + cocos2d::EventListenerMouse* _lis; +}; + #endif diff --git a/tests/cpp-tests/Resources/InputTest/cursor1.png b/tests/cpp-tests/Resources/InputTest/cursor1.png new file mode 100644 index 0000000000000000000000000000000000000000..973d3eafe0e7f12df5b8a76d5f8efbadf696fe3f GIT binary patch literal 760 zcmVd^2KUCJeb(I1zoOCf8v+15y_)uLl`=ulA5sScHGCPT~3g~bXa*ToKYam%e? zE(|;R&v*P*CPBK|_I%+3@AD4Ehxd7ZFTdYgq9_VUPAStNUGN6u5NoLX%5}6` z8YRl_oA4H6g}0OioGpmlW7?SSQubgbwFi$-I-SPw6!U;tAZib8+_Y7x($y%5L?S!o zWXg)Y2TNzl27@6wbXZT*)6*!AGEbRBB3hhHDD;u)^bIsQ8ADma^f8OY2qNR-VQMn8 zP$cpR9o;ABO~uo?qvMTYB7RHEcS)k&a_h?@DAlRRdSseL1b#`E1Aqz8X9_wax?Rq*&s#` z!TD%1TgdN!gK|BC!4@%sNIV`VbGwxW2VbFFtG0WG7(pbNOlDScz=xBERxz;MB}NcQ zrBY-vS*X9?i*ki}1XYR=%;v1cM!kK{FkHs?n7yI|5u2@(-0ofsmoU$nDp7*S`HqX! z)8i)f#R9gqq6Cr73wCn3@PSx1! z#wbbZcIq3` ztsdsZ5iBoXLnjQ4q}A@Gii+(&-_+Fa?7Qli3NDCMYB*j`I^F)6(*fo-<5X8K=V{oWmbmqQ!y`*{&YWB@HWo1 q#l>smUjzf{YPs_HH0GKg0t^7?$UIKeh%?Cm0000~)nP$k>V8FvHeIz*H;s5-^#{Dfb^>lZ1gxKa! zRl44lbo1FePnXUEBA+x_kKgIah}?erx6L=TJrB)099Wb#lsCFfV(}0~s7WeyXI`n#{}3vcEX1ND(AfA( f!E@0Ap#%o|Qq{oUwyYdLXEAuX`njxgN@xNAng3cO literal 0 HcmV?d00001