From f65459d0e1ea385da370ae8ecc8ee7fcaf89b268 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Wed, 15 Jun 2016 23:02:09 +0200 Subject: [PATCH] Rewrote Cursor with new API and OS X implementation --- include/SFML/Window.hpp | 1 + include/SFML/Window/ContextSettings.hpp | 1 + include/SFML/Window/Cursor.hpp | 214 ++++++++++++++ include/SFML/Window/Window.hpp | 63 +---- src/SFML/Window/Android/WindowImplAndroid.cpp | 9 +- src/SFML/Window/Android/WindowImplAndroid.hpp | 14 +- src/SFML/Window/CMakeLists.txt | 13 + src/SFML/Window/Cursor.cpp | 73 +++++ src/SFML/Window/CursorImpl.hpp | 56 ++++ src/SFML/Window/OSX/CursorImpl.hpp | 109 ++++++++ src/SFML/Window/OSX/CursorImpl.mm | 97 +++++++ src/SFML/Window/OSX/SFOpenGLView+mouse.mm | 19 ++ src/SFML/Window/OSX/SFOpenGLView.h | 7 + src/SFML/Window/OSX/SFOpenGLView.mm | 1 + src/SFML/Window/OSX/SFViewController.mm | 7 + src/SFML/Window/OSX/SFWindowController.mm | 7 + src/SFML/Window/OSX/WindowImplCocoa.hpp | 14 +- src/SFML/Window/OSX/WindowImplCocoa.mm | 11 +- .../Window/OSX/WindowImplDelegateProtocol.h | 6 + src/SFML/Window/Unix/CursorImpl.cpp | 66 +++++ src/SFML/Window/Unix/CursorImpl.hpp | 94 +++++++ src/SFML/Window/Unix/WindowImplX11.cpp | 261 +----------------- src/SFML/Window/Unix/WindowImplX11.hpp | 16 +- src/SFML/Window/Win32/CursorImpl.cpp | 66 +++++ src/SFML/Window/Win32/CursorImpl.hpp | 95 +++++++ src/SFML/Window/Win32/WindowImplWin32.cpp | 44 +-- src/SFML/Window/Win32/WindowImplWin32.hpp | 14 +- src/SFML/Window/Window.cpp | 12 +- src/SFML/Window/WindowImpl.hpp | 17 +- src/SFML/Window/iOS/WindowImplUIKit.hpp | 14 +- src/SFML/Window/iOS/WindowImplUIKit.mm | 9 +- 31 files changed, 961 insertions(+), 469 deletions(-) create mode 100644 include/SFML/Window/Cursor.hpp create mode 100644 src/SFML/Window/Cursor.cpp create mode 100644 src/SFML/Window/CursorImpl.hpp create mode 100644 src/SFML/Window/OSX/CursorImpl.hpp create mode 100644 src/SFML/Window/OSX/CursorImpl.mm create mode 100644 src/SFML/Window/Unix/CursorImpl.cpp create mode 100644 src/SFML/Window/Unix/CursorImpl.hpp create mode 100644 src/SFML/Window/Win32/CursorImpl.cpp create mode 100644 src/SFML/Window/Win32/CursorImpl.hpp diff --git a/include/SFML/Window.hpp b/include/SFML/Window.hpp index eefe2678..b945da10 100644 --- a/include/SFML/Window.hpp +++ b/include/SFML/Window.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/include/SFML/Window/ContextSettings.hpp b/include/SFML/Window/ContextSettings.hpp index 27743029..e56244c4 100644 --- a/include/SFML/Window/ContextSettings.hpp +++ b/include/SFML/Window/ContextSettings.hpp @@ -25,6 +25,7 @@ #ifndef SFML_CONTEXTSETTINGS_HPP #define SFML_CONTEXTSETTINGS_HPP +#include namespace sf { diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp new file mode 100644 index 00000000..f190a4de --- /dev/null +++ b/include/SFML/Window/Cursor.hpp @@ -0,0 +1,214 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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 SFML_CURSOR_HPP +#define SFML_CURSOR_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + +namespace sf +{ +namespace priv +{ + class CursorImpl; +} + +//////////////////////////////////////////////////////////// +/// \brief Cursor defines the appearance of a system cursor +/// +//////////////////////////////////////////////////////////// +class SFML_WINDOW_API Cursor : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Enumeration of the native system cursor types + /// + /// Refer to the following table to determine which cursor + /// is available on which platform. + /// + /// Type | Linux | Mac OS X | Windows + /// ------------------------------------|:-----:|:--------:|:--------: + /// sf::Cursor::Arrow | yes | yes | yes + /// sf::Cursor::ArrowWait | no | no | no + /// sf::Cursor::Wait | no | no | no + /// sf::Cursor::Text | no | yes | no + /// sf::Cursor::Hand | no | yes | no + /// sf::Cursor::SizeHorizontal | no | yes | no + /// sf::Cursor::SizeVertical | no | yes | no + /// sf::Cursor::SizeTopLeftBottomRight | no | no | no + /// sf::Cursor::SizeBottomLeftTopRight | no | no | no + /// sf::Cursor::SizeAll | no | no | no + /// sf::Cursor::Cross | no | yes | no + /// sf::Cursor::Help | no | no | no + /// sf::Cursor::NotAllowed | no | yes | no + /// + //////////////////////////////////////////////////////////// + enum Type + { + Arrow, ///< Arrow cursor (default) + ArrowWait, ///< Busy arrow cursor + Wait, ///< Busy cursor + Text, ///< I-beam, cursor when hovering over a field allowing text entry + Hand, ///< Pointing hand cursor + SizeHorizontal, ///< Horizontal double arrow cursor + SizeVertical, ///< Vertical double arrow cursor + SizeTopLeftBottomRight, ///< Double arrow cursor going from top-left to bottom-right + SizeBottomLeftTopRight, ///< Double arrow cursor going from bottom-left to top-right + SizeAll, ///< Combination of SizeHorizontal and SizeVertical + Cross, ///< Crosshair cursor + Help, ///< Help cursor + NotAllowed ///< Action not allowed cursor + }; + +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor doesn't actually create the cursor; + /// initially the new instance is invalid and must not be + /// used until either loadFromPixels() or loadFromSystem() + /// is called and successfully created a cursor. + /// + //////////////////////////////////////////////////////////// + Cursor(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// This destructor releases the system resources + /// associated with this cursor, if any. + /// + //////////////////////////////////////////////////////////// + ~Cursor(); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image + /// + /// \a pixels must be an array of \a width by \a height pixels + /// in 32-bit RGBA format. If not, this will cause undefined behavior. + /// + /// If \a pixels is null or either \a width or \a height are 0, + /// the current cursor is left unchanged and the function will + /// return false. + /// + /// In addition to specifying the pixel data, you can also + /// specify the location of the hotspot of the cursor. The + /// hotspot is the pixel coordinate within the cursor image + /// which will be located exactly where the mouse pointer + /// position is. Any mouse actions that are performed will + /// return the window/screen location of the hotspot. + /// + /// \param pixels Array of pixels of the image + /// \param size Width and height of the image + /// \param hotspot (x,y) location of the hotspot + /// \return true if the cursor was successfully loaded; + /// false otherwise + /// + //////////////////////////////////////////////////////////// + bool loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot); + + //////////////////////////////////////////////////////////// + /// \brief Create a native system cursor + /// + /// Refer to the list of cursor available on each system + /// (see sf::Cursor::Type) to know whether a given cursor is + /// expected to load successfully or is not supported by + /// the operating system. + /// + /// \param type Native system cursor type + /// \return true if and only if the corresponding cursor is + /// natively supported by the operating system; + /// false otherwise + /// + //////////////////////////////////////////////////////////// + bool loadFromSystem(Type type); + +private: + + friend class Window; + + //////////////////////////////////////////////////////////// + /// \brief Get access to the underlying implementation + /// + /// This is primarily designed for sf::Window::setMouseCursor, + /// hence the friendship. + /// + /// \return a reference to the OS-specific implementation + /// + //////////////////////////////////////////////////////////// + const priv::CursorImpl& getImpl() const; + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + priv::CursorImpl* m_impl; ///< Platform-specific implementation of the cursor +}; + +} // namespace sf + + +#endif // SFML_CURSOR_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Cursor +/// \ingroup window +/// +/// \warning Features related to Cursor are not supported on +/// iOS and Android. +/// +/// This class abstracts the operating system resources +/// associated with either a native system cursor or a custom +/// cursor. +/// +/// After loading the cursor the graphical appearance +/// with either loadFromPixels() or loadFromSystem(), the +/// cursor can be changed with sf::Window::setMouseCursor(). +/// +/// \todo Does Windows or Linux requires the Cursor instance +/// to outlive it's usage? +/// +/// Usage example: +/// \code +/// sf::Window window; +/// +/// // ... create window as usual ... +/// +/// sf::Cursor cursor; +/// if (cursor.loadFromSystem(sf::Cursor::Hand)) +/// window.setMouseCursor(cursor); +/// \endcode +/// +/// \see sf::Window::setMouseCursor +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 3a0534f8..c9fc2c27 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -28,16 +28,17 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include #include +#include +#include +#include #include #include #include -#include #include -#include #include #include +#include namespace sf @@ -56,29 +57,6 @@ class Event; //////////////////////////////////////////////////////////// class SFML_WINDOW_API Window : GlResource, NonCopyable { -public: - - //////////////////////////////////////////////////////////// - /// \brief Enumeration of the native system cursor types - /// - //////////////////////////////////////////////////////////// - enum Cursor - { - Arrow, ///< Arrow cursor (default) - ArrowWait, ///< Busy arrow cursor - Wait, ///< Busy cursor - Text, ///< I-beam, cursor when hovering over a field allowing text entry - Hand, ///< Pointing hand cursor - SizeHorizontal, ///< Horizontal double arrow cursor - SizeVertical, ///< Vertical double arrow cursor - SizeTopLeftBottomRight, ///< Double arrow cursor going from top-left to bottom-right - SizeBottomLeftTopRight, ///< Double arrow cursor going from bottom-left to top-right - SizeAll, ///< Combination of CursorSizeHorizontal and CursorSizeVertical - Cross, ///< Crosshair cursor - Help, ///< Help cursor - NotAllowed ///< Action not allowed cursor - }; - public: //////////////////////////////////////////////////////////// @@ -389,37 +367,16 @@ public: /// /// Upon window creation, the arrow cursor is used by default. /// + /// \warning Features related to Cursor are not supported on + /// iOS and Android. + /// /// \param cursor Native system cursor type to display /// - //////////////////////////////////////////////////////////// - void setMouseCursor(Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \a pixels must be an array of \a width x \a height pixels - /// in 32-bit RGBA format. If not, this will cause undefined behavior. - /// - /// If \a pixels is null or either \a width or \a height are 0, - /// the current cursor is left unchanged. - /// - /// In addition to specifying the pixel data, you can also - /// specify the location of the hotspot of the cursor. The - /// hotspot is the pixel coordinate within the cursor image - /// which will be located exactly where the mouse pointer - /// position is. Any mouse actions that are performed will - /// return the window/screen location of the hotspot. - /// - /// Upon window creation, the arrow cursor is used by default. - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot + /// \see sf::Cursor::loadFromSystem + /// \see sf::Cursor::loadFromPixels /// //////////////////////////////////////////////////////////// - void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + void setMouseCursor(const Cursor& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/Android/WindowImplAndroid.cpp b/src/SFML/Window/Android/WindowImplAndroid.cpp index 2f83be8f..405f7c8a 100644 --- a/src/SFML/Window/Android/WindowImplAndroid.cpp +++ b/src/SFML/Window/Android/WindowImplAndroid.cpp @@ -186,14 +186,7 @@ void WindowImplAndroid::setMouseCursorGrabbed(bool grabbed) //////////////////////////////////////////////////////////// -void WindowImplAndroid::setMouseCursor(Window::Cursor cursor) -{ - // Not applicable -} - - -//////////////////////////////////////////////////////////// -void WindowImplAndroid::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) +void WindowImplAndroid::setMouseCursor(const CursorImpl& cursor) { // Not applicable } diff --git a/src/SFML/Window/Android/WindowImplAndroid.hpp b/src/SFML/Window/Android/WindowImplAndroid.hpp index c201f038..76361440 100644 --- a/src/SFML/Window/Android/WindowImplAndroid.hpp +++ b/src/SFML/Window/Android/WindowImplAndroid.hpp @@ -160,19 +160,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + virtual void setMouseCursor(const CursorImpl& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index a887766e..ee549968 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -6,6 +6,9 @@ set(SRCROOT ${PROJECT_SOURCE_DIR}/src/SFML/Window) set(SRC ${SRCROOT}/Context.cpp ${INCROOT}/Context.hpp + ${SRCROOT}/Cursor.cpp + ${INCROOT}/Cursor.hpp + ${SRCROOT}/CursorImpl.hpp ${INCROOT}/Export.hpp ${SRCROOT}/GlContext.cpp ${SRCROOT}/GlContext.hpp @@ -51,6 +54,8 @@ source_group("" FILES ${SRC}) # add platform specific sources if(SFML_OS_WINDOWS) set(PLATFORM_SRC + ${SRCROOT}/Win32/CursorImpl.hpp + ${SRCROOT}/Win32/CursorImpl.cpp ${SRCROOT}/Win32/WglContext.cpp ${SRCROOT}/Win32/WglContext.hpp ${SRCROOT}/Win32/WglExtensions.cpp @@ -71,6 +76,8 @@ if(SFML_OS_WINDOWS) add_definitions(-DUNICODE -D_UNICODE) elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD) set(PLATFORM_SRC + ${SRCROOT}/Unix/CursorImpl.hpp + ${SRCROOT}/Unix/CursorImpl.cpp ${SRCROOT}/Unix/Display.cpp ${SRCROOT}/Unix/Display.hpp ${SRCROOT}/Unix/InputImpl.cpp @@ -110,6 +117,8 @@ elseif(SFML_OS_MACOSX) ${SRCROOT}/OSX/cpp_objc_conversion.mm ${SRCROOT}/OSX/cg_sf_conversion.hpp ${SRCROOT}/OSX/cg_sf_conversion.mm + ${SRCROOT}/OSX/CursorImpl.hpp + ${SRCROOT}/OSX/CursorImpl.mm ${SRCROOT}/OSX/InputImpl.mm ${SRCROOT}/OSX/InputImpl.hpp ${SRCROOT}/OSX/HIDInputManager.hpp @@ -155,6 +164,8 @@ elseif(SFML_OS_MACOSX) source_group("mac" FILES ${PLATFORM_SRC}) elseif(SFML_OS_IOS) set(PLATFORM_SRC + ${SRCROOT}/iOS/CursorImpl.hpp + ${SRCROOT}/iOS/CursorImpl.cpp ${SRCROOT}/iOS/EaglContext.mm ${SRCROOT}/iOS/EaglContext.hpp ${SRCROOT}/iOS/InputImpl.mm @@ -179,6 +190,8 @@ elseif(SFML_OS_IOS) source_group("ios" FILES ${PLATFORM_SRC}) elseif(SFML_OS_ANDROID) set(PLATFORM_SRC + ${SRCROOT}/Android/CursorImpl.hpp + ${SRCROOT}/Android/CursorImpl.cpp ${SRCROOT}/Android/WindowImplAndroid.hpp ${SRCROOT}/Android/WindowImplAndroid.cpp ${SRCROOT}/Android/VideoModeImpl.cpp diff --git a/src/SFML/Window/Cursor.cpp b/src/SFML/Window/Cursor.cpp new file mode 100644 index 00000000..c0585e14 --- /dev/null +++ b/src/SFML/Window/Cursor.cpp @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + +namespace sf +{ + +//////////////////////////////////////////////////////////// +Cursor::Cursor() : +m_impl(new priv::CursorImpl()) +{ + // That's it +} + + +//////////////////////////////////////////////////////////// +Cursor::~Cursor() +{ + delete m_impl; +} + + +//////////////////////////////////////////////////////////// +bool Cursor::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + if ((pixels == 0) || (size.x == 0) || (size.y == 0)) + return false; + else + return m_impl->loadFromPixels(pixels, size, hotspot); +} + + +//////////////////////////////////////////////////////////// +bool Cursor::loadFromSystem(Type type) +{ + return m_impl->loadFromSystem(type); +} + + +//////////////////////////////////////////////////////////// +const priv::CursorImpl& Cursor::getImpl() const +{ + return *m_impl; +} + +} // namespace sf + diff --git a/src/SFML/Window/CursorImpl.hpp b/src/SFML/Window/CursorImpl.hpp new file mode 100644 index 00000000..210c61de --- /dev/null +++ b/src/SFML/Window/CursorImpl.hpp @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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 SFML_CURSORIMPL_HPP +#define SFML_CURSORIMPL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#if defined(SFML_SYSTEM_WINDOWS) + + #include + +#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) + + #include + +#elif defined(SFML_SYSTEM_MACOS) + + #include + +#elif defined(SFML_SYSTEM_IOS) + + #include + +#elif defined(SFML_SYSTEM_ANDROID) + + #include + +#endif + + +#endif // SFML_CURSORIMPL_HPP diff --git a/src/SFML/Window/OSX/CursorImpl.hpp b/src/SFML/Window/OSX/CursorImpl.hpp new file mode 100644 index 00000000..01b24ed3 --- /dev/null +++ b/src/SFML/Window/OSX/CursorImpl.hpp @@ -0,0 +1,109 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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 SFML_CURSORIMPLOSX_HPP +#define SFML_CURSORIMPLOSX_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + +//////////////////////////////////////////////////////////// +// Predefine OBJ-C classes +//////////////////////////////////////////////////////////// +#ifdef __OBJC__ + +@class NSCursor; +typedef NSCursor* NSCursorRef; + +#else // If C++ + +typedef void* NSCursorRef; + +#endif + +namespace sf +{ + +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Mac OS X implementation of Cursor +/// +//////////////////////////////////////////////////////////// +class CursorImpl : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Refer to sf::Cursor::Cursor(). + /// + //////////////////////////////////////////////////////////// + CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// Refer to sf::Cursor::~Cursor(). + /// + //////////////////////////////////////////////////////////// + ~CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image + /// + /// Refer to sf::Cursor::loadFromPixels(). + /// + //////////////////////////////////////////////////////////// + bool loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot); + + //////////////////////////////////////////////////////////// + /// \brief Create a native system cursor + /// + /// Refer to sf::Cursor::loadFromSystem(). + /// + //////////////////////////////////////////////////////////// + bool loadFromSystem(Cursor::Type type); + +private: + + friend class WindowImplCocoa; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + NSCursorRef m_cursor; ///< System cursor handle +}; + +} // namespace priv + +} // namespace sf + +#endif // SFML_CURSORIMPLOSX_HPP diff --git a/src/SFML/Window/OSX/CursorImpl.mm b/src/SFML/Window/OSX/CursorImpl.mm new file mode 100644 index 00000000..bf2599c6 --- /dev/null +++ b/src/SFML/Window/OSX/CursorImpl.mm @@ -0,0 +1,97 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#import +#import +#import + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +CursorImpl::CursorImpl() : +m_cursor(nil) +{ + // Just ask for a pool + ensureThreadHasPool(); +} + + +//////////////////////////////////////////////////////////// +CursorImpl::~CursorImpl() +{ + [m_cursor release]; +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + NSSize nssize = NSMakeSize(size.x, size.y); + NSImage* image = [NSImage imageWithRawData:pixels andSize:nssize]; + NSPoint nshotspot = NSMakePoint(hotspot.x, hotspot.y); + + m_cursor = [[NSCursor alloc] initWithImage:image hotSpot:nshotspot]; + + return m_cursor != nil; +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromSystem(Cursor::Type type) +{ + switch (type) + { + default: return false; + + case Cursor::Arrow: m_cursor = [NSCursor arrowCursor]; break; + case Cursor::Text: m_cursor = [NSCursor IBeamCursor]; break; + case Cursor::Hand: m_cursor = [NSCursor pointingHandCursor]; break; + case Cursor::SizeHorizontal: m_cursor = [NSCursor resizeLeftRightCursor]; break; + case Cursor::SizeVertical: m_cursor = [NSCursor resizeUpDownCursor]; break; + case Cursor::Cross: m_cursor = [NSCursor crosshairCursor]; break; + case Cursor::NotAllowed: m_cursor = [NSCursor operationNotAllowedCursor]; break; + } + + // Since we didn't allocate the cursor ourself, we have to retain it + // in order to not break the retain count. + [m_cursor retain]; + + // For all non-default cases, it was a success. + return true; +} + + +} // namespace priv + +} // namespace sf + diff --git a/src/SFML/Window/OSX/SFOpenGLView+mouse.mm b/src/SFML/Window/OSX/SFOpenGLView+mouse.mm index fa65aa6e..f56e1564 100644 --- a/src/SFML/Window/OSX/SFOpenGLView+mouse.mm +++ b/src/SFML/Window/OSX/SFOpenGLView+mouse.mm @@ -40,6 +40,25 @@ @implementation SFOpenGLView (mouse) +//////////////////////////////////////////////////////// +-(void)setCursor:(NSCursor*)cursor +{ + m_cursor = cursor; + + // indirect call to resetCursorRects to set the cursor + [self.window invalidateCursorRectsForView:self]; +} + + +//////////////////////////////////////////////////////// +-(void)resetCursorRects +{ + // addCursorRect:cursor: has to be called from within this function! + [self addCursorRect:[self frame] cursor:m_cursor]; + [m_cursor setOnMouseEntered:YES]; +} + + //////////////////////////////////////////////////////// -(BOOL)isMouseInside { diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index d25b1b24..4e1fe95a 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -71,6 +71,7 @@ namespace sf { sf::priv::WindowImplCocoa* m_requester; ///< View's requester BOOL m_useKeyRepeat; ///< Key repeat setting BOOL m_mouseIsIn; ///< Mouse positional state + NSCursor* m_cursor; ///< Active cursor NSTrackingArea* m_trackingArea; ///< Mouse tracking area BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not CGFloat m_scaleFactor; ///< Display scale factor (e.g. 1x for classic display, 2x for retina) @@ -154,6 +155,12 @@ namespace sf { @interface SFOpenGLView (mouse) +//////////////////////////////////////////////////////////// +/// \brief Set the system cursor for the window area +/// +//////////////////////////////////////////////////////////// +-(void)setCursor:(NSCursor*)cursor; + //////////////////////////////////////////////////////////// /// \brief Compute the position of the cursor /// diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index aa51de16..3119e127 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -111,6 +111,7 @@ m_cursorGrabbed = NO; m_deltaXBuffer = 0; m_deltaYBuffer = 0; + m_cursor = [NSCursor arrowCursor]; // Create a hidden text view for parsing key down event properly m_silentResponder = [[SFSilentResponder alloc] init]; diff --git a/src/SFML/Window/OSX/SFViewController.mm b/src/SFML/Window/OSX/SFViewController.mm index 03b161fc..1b48fe07 100644 --- a/src/SFML/Window/OSX/SFViewController.mm +++ b/src/SFML/Window/OSX/SFViewController.mm @@ -128,6 +128,13 @@ } +//////////////////////////////////////////////////////// +-(void)setCursor:(NSCursor*)cursor +{ + return [m_oglView setCursor:cursor]; +} + + //////////////////////////////////////////////////////////// -(NSPoint)position { diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index b12db9b6..3d952082 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -371,6 +371,13 @@ } +//////////////////////////////////////////////////////// +-(void)setCursor:(NSCursor*)cursor +{ + return [m_oglView setCursor:cursor]; +} + + //////////////////////////////////////////////////////////// -(NSPoint)position { diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp index 4df291ad..e47e7a73 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.hpp +++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp @@ -327,19 +327,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + virtual void setMouseCursor(const CursorImpl& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm index 2e966ff1..b0482501 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.mm +++ b/src/SFML/Window/OSX/WindowImplCocoa.mm @@ -494,16 +494,9 @@ void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed) //////////////////////////////////////////////////////////// -void WindowImplCocoa::setMouseCursor(Window::Cursor cursor) +void WindowImplCocoa::setMouseCursor(const CursorImpl& cursor) { - // TODO: Implement OS X cursor setting -} - - -//////////////////////////////////////////////////////////// -void WindowImplCocoa::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) -{ - // TODO: Implement OS X cursor setting + [m_delegate setCursor:cursor.m_cursor]; } diff --git a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h index 0ca85625..baac0989 100644 --- a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h +++ b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h @@ -104,6 +104,12 @@ namespace sf { //////////////////////////////////////////////////////////// -(void)setCursorGrabbed:(BOOL)grabbed; +//////////////////////////////////////////////////////////// +/// \brief Set the system cursor for the window area +/// +//////////////////////////////////////////////////////////// +-(void)setCursor:(NSCursor*)cursor; + //////////////////////////////////////////////////////////// /// \brief Get window position /// diff --git a/src/SFML/Window/Unix/CursorImpl.cpp b/src/SFML/Window/Unix/CursorImpl.cpp new file mode 100644 index 00000000..3791feca --- /dev/null +++ b/src/SFML/Window/Unix/CursorImpl.cpp @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +CursorImpl::CursorImpl() +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +CursorImpl::~CursorImpl() +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromSystem(Cursor::Type type) +{ + // TODO +} + + +} // namespace priv + +} // namespace sf + diff --git a/src/SFML/Window/Unix/CursorImpl.hpp b/src/SFML/Window/Unix/CursorImpl.hpp new file mode 100644 index 00000000..245714ef --- /dev/null +++ b/src/SFML/Window/Unix/CursorImpl.hpp @@ -0,0 +1,94 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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 SFML_CURSORIMPLUNIX_HPP +#define SFML_CURSORIMPLUNIX_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ + +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Unix implementation of Cursor +/// +//////////////////////////////////////////////////////////// +class CursorImpl : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Refer to sf::Cursor::Cursor(). + /// + //////////////////////////////////////////////////////////// + CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// Refer to sf::Cursor::~Cursor(). + /// + //////////////////////////////////////////////////////////// + ~CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image + /// + /// Refer to sf::Cursor::loadFromPixels(). + /// + //////////////////////////////////////////////////////////// + bool loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot); + + //////////////////////////////////////////////////////////// + /// \brief Create a native system cursor + /// + /// Refer to sf::Cursor::loadFromSystem(). + /// + //////////////////////////////////////////////////////////// + bool loadFromSystem(Cursor::Type type); + +private: + + friend class WindowImplX11; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// +}; + +} // namespace priv + +} // namespace sf + +#endif // SFML_CUSROSIMPLUNIX_HPP diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 63d6f267..13d679f7 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -901,246 +901,9 @@ void WindowImplX11::setMouseCursorVisible(bool visible) //////////////////////////////////////////////////////////// -void WindowImplX11::setMouseCursor(Window::Cursor cursor) +void WindowImplX11::setMouseCursor(const CursorImpl& cursor) { - xcb_cursor_t newCursor = 0; - - xcb_cursor_context_t* cursorContext = NULL; - - if (xcb_cursor_context_new(m_connection, m_screen, &cursorContext) < 0) - { - err() << "Could not create XCB cursor context" << std::endl; - return; - } - - switch(cursor) - { - case Window::Arrow: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break; - case Window::ArrowWait: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break; - case Window::Wait: newCursor = xcb_cursor_load_cursor(cursorContext, "watch"); break; - case Window::Text: newCursor = xcb_cursor_load_cursor(cursorContext, "xterm"); break; - case Window::Hand: newCursor = xcb_cursor_load_cursor(cursorContext, "hand2"); break; - case Window::SizeHorizontal: newCursor = xcb_cursor_load_cursor(cursorContext, "sb_h_double_arrow"); break; - case Window::SizeVertical: newCursor = xcb_cursor_load_cursor(cursorContext, "sb_v_double_arrow"); break; - case Window::SizeTopLeftBottomRight: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break; - case Window::SizeBottomLeftTopRight: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break; - case Window::SizeAll: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break; - case Window::Cross: newCursor = xcb_cursor_load_cursor(cursorContext, "crosshair"); break; - case Window::Help: newCursor = xcb_cursor_load_cursor(cursorContext, "question_arrow"); break; - case Window::NotAllowed: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break; - default: break; - } - - xcb_cursor_context_free(cursorContext); - - if (m_loadedCursor) - xcb_free_cursor(m_connection, m_loadedCursor); - - if (!newCursor) - return; - - m_loadedCursor = newCursor; - - if (!m_cursor) - return; - - ScopedXcbPtr changeAttributesError(xcb_request_check( - m_connection, - xcb_change_window_attributes( - m_connection, - m_window, - XCB_CW_CURSOR, - &m_loadedCursor - ) - )); - - if (changeAttributesError) - { - err() << "Failed to change window attributes" << std::endl; - return; - } - - m_cursor = m_loadedCursor; -} - - -//////////////////////////////////////////////////////////// -void WindowImplX11::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) -{ - // Get the picture format from XCB - ScopedXcbPtr pictFormatsreply(xcb_render_query_pict_formats_reply( - m_connection, - xcb_render_query_pict_formats( - m_connection - ), - NULL - )); - - xcb_render_pictformat_t pictureFormat = xcb_render_util_find_standard_format(pictFormatsreply.get(), XCB_PICT_STANDARD_ARGB_32)->id; - - if (!pictureFormat) - { - err() << "Failed to get picture format from XCB" << std::endl; - return; - } - - // X11 wants BGRA pixels: swap red and blue channels - Uint8 cursorPixels[width * height * 4]; - for (std::size_t i = 0; i < width * height; ++i) - { - cursorPixels[i * 4 + 0] = pixels[i * 4 + 2]; - cursorPixels[i * 4 + 1] = pixels[i * 4 + 1]; - cursorPixels[i * 4 + 2] = pixels[i * 4 + 0]; - cursorPixels[i * 4 + 3] = pixels[i * 4 + 3]; - } - - xcb_pixmap_t cursorPixmap = xcb_generate_id(m_connection); - ScopedXcbPtr pixmapError(xcb_request_check( - m_connection, - xcb_create_pixmap( - m_connection, - 32, - cursorPixmap, - m_window, - width, - height - ) - )); - - if (pixmapError) - { - err() << "Failed to create XCB cursor pixmap" << std::endl; - return; - } - - xcb_gcontext_t cursorGC = xcb_generate_id(m_connection); - ScopedXcbPtr gcError(xcb_request_check( - m_connection, - xcb_create_gc( - m_connection, - cursorGC, - cursorPixmap, - 0, - NULL - ) - )); - - if (gcError) - { - err() << "Failed to create XCB graphics context" << std::endl; - xcb_free_pixmap(m_connection, cursorPixmap); - return; - } - - xcb_image_t* cursorImage = xcb_image_create_native( - m_connection, - width, - height, - XCB_IMAGE_FORMAT_Z_PIXMAP, - 32, - NULL, - width * height * 4, - cursorPixels - ); - - if (!cursorImage) - { - err() << "Failed to create XCB cursor image" << std::endl; - xcb_free_gc(m_connection, cursorGC); - xcb_free_pixmap(m_connection, cursorPixmap); - return; - } - - ScopedXcbPtr imagePutError(xcb_request_check( - m_connection, - xcb_image_put( - m_connection, - cursorPixmap, - cursorGC, - cursorImage, - 0, - 0, - 0 - ) - )); - - if (imagePutError) - { - err() << "Failed to put XCB image on the X server" << std::endl; - xcb_image_destroy(cursorImage); - xcb_free_gc(m_connection, cursorGC); - xcb_free_pixmap(m_connection, cursorPixmap); - return; - } - - xcb_render_picture_t cursorPicture = xcb_generate_id(m_connection); - ScopedXcbPtr createPictureError(xcb_request_check( - m_connection, - xcb_render_create_picture( - m_connection, - cursorPicture, - cursorPixmap, - pictureFormat, - 0, - NULL - ) - )); - - if (createPictureError) - { - err() << "Failed to create XCB cursor picture" << std::endl; - xcb_image_destroy(cursorImage); - xcb_free_gc(m_connection, cursorGC); - xcb_free_pixmap(m_connection, cursorPixmap); - return; - } - - xcb_cursor_t newCursor = xcb_generate_id(m_connection); - ScopedXcbPtr createCursorError(xcb_request_check( - m_connection, - xcb_render_create_cursor( - m_connection, - newCursor, - cursorPicture, - hotspotX, - hotspotY - ) - )); - - xcb_render_free_picture(m_connection, cursorPicture); - xcb_image_destroy(cursorImage); - xcb_free_gc(m_connection, cursorGC); - xcb_free_pixmap(m_connection, cursorPixmap); - - if (createCursorError) - { - err() << "Failed to create XCB cursor" << std::endl; - return; - } - - xcb_free_cursor(m_connection, m_loadedCursor); - m_loadedCursor = newCursor; - - if (!m_cursor) - return; - - ScopedXcbPtr changeAttributesError(xcb_request_check( - m_connection, - xcb_change_window_attributes( - m_connection, - m_window, - XCB_CW_CURSOR, - &m_loadedCursor - ) - )); - - if (changeAttributesError) - { - err() << "Failed to change window attributes" << std::endl; - return; - } - - m_cursor = m_loadedCursor; + // TODO } @@ -1583,26 +1346,6 @@ void WindowImplX11::updateLastInputTime(::Time time) } -//////////////////////////////////////////////////////////// -void WindowImplX11::createHiddenCursor() -{ - // Create the cursor's pixmap (1x1 pixels) - Pixmap cursorPixmap = XCreatePixmap(m_display, m_window, 1, 1, 1); - GC graphicsContext = XCreateGC(m_display, cursorPixmap, 0, NULL); - XDrawPoint(m_display, cursorPixmap, graphicsContext, 0, 0); - XFreeGC(m_display, graphicsContext); - - // Create the cursor, using the pixmap as both the shape and the mask of the cursor - XColor color; - color.flags = DoRed | DoGreen | DoBlue; - color.red = color.blue = color.green = 0; - m_hiddenCursor = XCreatePixmapCursor(m_display, cursorPixmap, cursorPixmap, &color, &color, 0, 0); - - // We don't need the pixmap any longer, free it - XFreePixmap(m_display, cursorPixmap); -} - - //////////////////////////////////////////////////////////// void WindowImplX11::cleanup() { diff --git a/src/SFML/Window/Unix/WindowImplX11.hpp b/src/SFML/Window/Unix/WindowImplX11.hpp index a732b0bd..631fefcc 100644 --- a/src/SFML/Window/Unix/WindowImplX11.hpp +++ b/src/SFML/Window/Unix/WindowImplX11.hpp @@ -160,19 +160,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + virtual void setMouseCursor(const CursorImpl& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat @@ -279,7 +267,7 @@ private: XIC m_inputContext; ///< Input context used to get unicode input in our window bool m_isExternal; ///< Tell whether the window has been created externally or by SFML int m_oldVideoMode; ///< Video mode in use before we switch to fullscreen - Cursor m_hiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one + ::Cursor m_hiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one bool m_keyRepeat; ///< Is the KeyRepeat feature enabled? Vector2i m_previousSize; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only) bool m_useSizeHints; ///< Is the size of the window fixed with size hints? diff --git a/src/SFML/Window/Win32/CursorImpl.cpp b/src/SFML/Window/Win32/CursorImpl.cpp new file mode 100644 index 00000000..146d54c1 --- /dev/null +++ b/src/SFML/Window/Win32/CursorImpl.cpp @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +CursorImpl::CursorImpl() +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +CursorImpl::~CursorImpl() +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + // TODO +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromSystem(Cursor::Type type) +{ + // TODO +} + + +} // namespace priv + +} // namespace sf + diff --git a/src/SFML/Window/Win32/CursorImpl.hpp b/src/SFML/Window/Win32/CursorImpl.hpp new file mode 100644 index 00000000..dcab6489 --- /dev/null +++ b/src/SFML/Window/Win32/CursorImpl.hpp @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without 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 SFML_CURSORIMPLWIN32_HPP +#define SFML_CURSORIMPLWIN32_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ + +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Win32 implementation of Cursor +/// +//////////////////////////////////////////////////////////// +class CursorImpl : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Refer to sf::Cursor::Cursor(). + /// + //////////////////////////////////////////////////////////// + CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// Refer to sf::Cursor::~Cursor(). + /// + //////////////////////////////////////////////////////////// + ~CursorImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image + /// + /// Refer to sf::Cursor::loadFromPixels(). + /// + //////////////////////////////////////////////////////////// + bool loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot); + + //////////////////////////////////////////////////////////// + /// \brief Create a native system cursor + /// + /// Refer to sf::Cursor::loadFromSystem(). + /// + //////////////////////////////////////////////////////////// + bool loadFromSystem(Cursor::Type type); + +private: + + friend class WindowImplWin32; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// +}; + +} // namespace priv + +} // namespace sf + +#endif // SFML_CUSROSIMPLWIN32_HPP + diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp index 68f1ee02..2056296b 100644 --- a/src/SFML/Window/Win32/WindowImplWin32.cpp +++ b/src/SFML/Window/Win32/WindowImplWin32.cpp @@ -224,7 +224,7 @@ m_cursorGrabbed (m_fullscreen) ++handleCount; } - + // By default, the OS limits the size of the window the the desktop size, // we have to resize it after creation to apply the real size setSize(Vector2u(mode.width, mode.height)); @@ -418,48 +418,8 @@ void WindowImplWin32::setMouseCursorGrabbed(bool grabbed) //////////////////////////////////////////////////////////// -void WindowImplWin32::setMouseCursor(Window::Cursor cursor) +void WindowImplWin32::setMouseCursor(const CursorImpl& cursor) { - HCURSOR newCursor = NULL; - - switch (cursor) - { - case Window::Arrow: newCursor = LoadCursor(NULL, IDC_ARROW); break; - case Window::ArrowWait: newCursor = LoadCursor(NULL, IDC_APPSTARTING); break; - case Window::Wait: newCursor = LoadCursor(NULL, IDC_WAIT); break; - case Window::Text: newCursor = LoadCursor(NULL, IDC_IBEAM); break; - case Window::Hand: newCursor = LoadCursor(NULL, IDC_HAND); break; - case Window::SizeHorizontal: newCursor = LoadCursor(NULL, IDC_SIZEWE); break; - case Window::SizeVertical: newCursor = LoadCursor(NULL, IDC_SIZENS); break; - case Window::SizeTopLeftBottomRight: newCursor = LoadCursor(NULL, IDC_SIZENWSE); break; - case Window::SizeBottomLeftTopRight: newCursor = LoadCursor(NULL, IDC_SIZENESW); break; - case Window::SizeAll: newCursor = LoadCursor(NULL, IDC_SIZEALL); break; - case Window::Cross: newCursor = LoadCursor(NULL, IDC_CROSS); break; - case Window::Help: newCursor = LoadCursor(NULL, IDC_HELP); break; - case Window::NotAllowed: newCursor = LoadCursor(NULL, IDC_NO); break; - default: return; - } - - // Create a copy of the shared system cursor that we can destroy later - newCursor = CopyCursor(newCursor); - - if (!newCursor) - { - err() << "Could not create copy of a system cursor" << std::endl; - return; - } - - HCURSOR oldCursor = m_loadedCursor; - m_loadedCursor = newCursor; - - if (m_cursor) - { - m_cursor = m_loadedCursor; - SetCursor(m_cursor); - } - - if (oldCursor) - DestroyCursor(oldCursor); } diff --git a/src/SFML/Window/Win32/WindowImplWin32.hpp b/src/SFML/Window/Win32/WindowImplWin32.hpp index 9dfe1671..289d6ae3 100644 --- a/src/SFML/Window/Win32/WindowImplWin32.hpp +++ b/src/SFML/Window/Win32/WindowImplWin32.hpp @@ -159,19 +159,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + virtual void setMouseCursor(const CursorImpl& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index 2e7a329c..1aed15c4 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -297,18 +297,10 @@ void Window::setMouseCursorGrabbed(bool grabbed) //////////////////////////////////////////////////////////// -void Window::setMouseCursor(Cursor cursor) +void Window::setMouseCursor(const Cursor& cursor) { if (m_impl) - m_impl->setMouseCursor(cursor); -} - - -//////////////////////////////////////////////////////////// -void Window::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) -{ - if (m_impl && pixels && width && height) - m_impl->setMouseCursor(pixels, width, height, hotspotX, hotspotY); + m_impl->setMouseCursor(cursor.getImpl()); } diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 1ade7f8c..6a6f75e7 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -201,19 +202,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor) = 0; - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) = 0; + virtual void setMouseCursor(const CursorImpl& cursor) = 0; //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/iOS/WindowImplUIKit.hpp b/src/SFML/Window/iOS/WindowImplUIKit.hpp index 7bc188ac..a3975fd8 100644 --- a/src/SFML/Window/iOS/WindowImplUIKit.hpp +++ b/src/SFML/Window/iOS/WindowImplUIKit.hpp @@ -163,19 +163,7 @@ public: /// \param cursor Native system cursor type to display /// //////////////////////////////////////////////////////////// - virtual void setMouseCursor(Window::Cursor cursor); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to the provided image - /// - /// \param pixels Array of pixels of the image - /// \param width Width of the image - /// \param height Height of the image - /// \param hotspotX X location of the hotspot - /// \param hotspotY Y location of the hotspot - /// - //////////////////////////////////////////////////////////// - virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY); + virtual void setMouseCursor(const CursorImpl& cursor); //////////////////////////////////////////////////////////// /// \brief Enable or disable automatic key-repeat diff --git a/src/SFML/Window/iOS/WindowImplUIKit.mm b/src/SFML/Window/iOS/WindowImplUIKit.mm index cc0e5b7f..72df19e7 100644 --- a/src/SFML/Window/iOS/WindowImplUIKit.mm +++ b/src/SFML/Window/iOS/WindowImplUIKit.mm @@ -191,14 +191,7 @@ void WindowImplUIKit::setMouseCursorGrabbed(bool grabbed) //////////////////////////////////////////////////////////// -void WindowImplUIKit::setMouseCursor(Window::Cursor cursor) -{ - // Not applicable -} - - -//////////////////////////////////////////////////////////// -void WindowImplUIKit::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) +void WindowImplUIKit::setMouseCursor(const CursorImpl& cursor) { // Not applicable }