diff --git a/include/SFML/Window.hpp b/include/SFML/Window.hpp index d7894e38..e38fb76b 100644 --- a/include/SFML/Window.hpp +++ b/include/SFML/Window.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index ff731080..1e368ad1 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -141,6 +141,17 @@ public : unsigned int button; ///< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1]) }; + //////////////////////////////////////////////////////////// + /// \brief Touch events parameters (TouchBegan, TouchMoved, TouchEnded) + /// + //////////////////////////////////////////////////////////// + struct TouchEvent + { + unsigned int finger; ///< Index of the finger in case of multi-touch events + int x; ///< X position of the touch, relative to the left of the owner window + int y; ///< Y position of the touch, relative to the top of the owner window + }; + //////////////////////////////////////////////////////////// /// \brief Enumeration of the different types of events /// @@ -165,6 +176,9 @@ public : JoystickMoved, ///< The joystick moved along an axis (data in event.joystickMove) JoystickConnected, ///< A joystick was connected (data in event.joystickConnect) JoystickDisconnected, ///< A joystick was disconnected (data in event.joystickConnect) + TouchBegan, ///< A touch event began (data in event.touch) + TouchMoved, ///< A touch moved (data in event.touch) + TouchEnded, ///< A touch event ended (data in event.touch) Count ///< Keep last -- the total number of event types }; @@ -185,6 +199,7 @@ public : JoystickMoveEvent joystickMove; ///< Joystick move event parameters (Event::JoystickMoved) JoystickButtonEvent joystickButton; ///< Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased) JoystickConnectEvent joystickConnect; ///< Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected) + TouchEvent touch; ///< Touch events parameters (Event::TouchBegan, Event::TouchMoved, Event::TouchEnded) }; }; diff --git a/include/SFML/Window/Keyboard.hpp b/include/SFML/Window/Keyboard.hpp index 76a855be..78211169 100644 --- a/include/SFML/Window/Keyboard.hpp +++ b/include/SFML/Window/Keyboard.hpp @@ -219,6 +219,6 @@ public : /// } /// \endcode /// -/// \see sf::Joystick, sf::Mouse +/// \see sf::Joystick, sf::Mouse, sf::Touch /// //////////////////////////////////////////////////////////// diff --git a/include/SFML/Window/Mouse.hpp b/include/SFML/Window/Mouse.hpp index 7d757d11..8d6b8f3a 100644 --- a/include/SFML/Window/Mouse.hpp +++ b/include/SFML/Window/Mouse.hpp @@ -162,6 +162,6 @@ public : /// sf::Mouse::setPosition(sf::Vector2i(100, 200), window); /// \endcode /// -/// \see sf::Joystick, sf::Keyboard +/// \see sf::Joystick, sf::Keyboard, sf::Touch /// //////////////////////////////////////////////////////////// diff --git a/include/SFML/Window/Touch.hpp b/include/SFML/Window/Touch.hpp new file mode 100644 index 00000000..61e6ba31 --- /dev/null +++ b/include/SFML/Window/Touch.hpp @@ -0,0 +1,138 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without 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_TOUCH_HPP +#define SFML_TOUCH_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +class Window; + +//////////////////////////////////////////////////////////// +/// \brief Give access to the real-time state of the touches +/// +//////////////////////////////////////////////////////////// +class SFML_WINDOW_API Touch +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getPosition(unsigned int finger, const Window& relativeTo); +}; + +} // namespace sf + + +#endif // SFML_TOUCH_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Touch +/// \ingroup window +/// +/// sf::Touch provides an interface to the state of the +/// touches. It only contains static functions, so it's not +/// meant to be instanciated. +/// +/// This class allows users to query the touches state at any +/// time and directly, without having to deal with a window and +/// its events. Compared to the TouchBegan, TouchMoved +/// and TouchEnded events, sf::Touch can retrieve the +/// state of the touches at any time (you don't need to store and +/// update a boolean on your side in order to know if a touch is down), +/// and you always get the real state of the touches, even if they +/// happen when your window is out of focus and no event is triggered. +/// +/// The setPosition and getPosition functions can be used to change +/// or retrieve the current position of the mouse pointer. There are +/// two versions: one that operates in global coordinates (relative +/// to the desktop) and one that operates in window coordinates +/// (relative to a specific window). +/// +/// Touches are identified by an index (the "finger"), so that in +/// multi-touch events, individual touches can be tracked correctly. +/// As long as a finger touches the screen, it will keep the same index +/// even if other fingers start or stop touching the screen in the +/// meantime. As a consequence, active touch indices may not always be +/// sequential (i.e. touch number 0 may be released while touch number 1 +/// is still down). +/// +/// Usage example: +/// \code +/// if (sf::Touch::isDown(0)) +/// { +/// // touch 0 is down +/// } +/// +/// // get global position of touch 1 +/// sf::Vector2i globalPos = sf::Touch::getPosition(4); +/// +/// // get position of touch 1 relative to a window +/// sf::Vector2i relativePos = sf::Touch::getPosition(4, window); +/// \endcode +/// +/// \see sf::Joystick, sf::Keyboard, sf::Mouse +/// +//////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/Android/InputImpl.cpp b/src/SFML/Window/Android/InputImpl.cpp index aa608823..034be254 100644 --- a/src/SFML/Window/Android/InputImpl.cpp +++ b/src/SFML/Window/Android/InputImpl.cpp @@ -169,6 +169,30 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ // Not applicable } + +//////////////////////////////////////////////////////////// +bool InputImpl::isTouchDown(unsigned int finger) +{ + // To implement + return false; +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int finger) +{ + // To implement + return Vector2i(); +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int finger, const Window& relativeTo) +{ + // To implement + return Vector2i(); +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Android/InputImpl.hpp b/src/SFML/Window/Android/InputImpl.hpp index 3ecbbe25..b5276cce 100644 --- a/src/SFML/Window/Android/InputImpl.hpp +++ b/src/SFML/Window/Android/InputImpl.hpp @@ -121,6 +121,43 @@ public : /// //////////////////////////////////////////////////////////// static void setMousePosition(const Vector2i& position, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isTouchDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index eb2233b5..7caca16c 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -23,6 +23,8 @@ set(SRC ${SRCROOT}/Keyboard.cpp ${INCROOT}/Mouse.hpp ${SRCROOT}/Mouse.cpp + ${INCROOT}/Touch.hpp + ${SRCROOT}/Touch.cpp ${SRCROOT}/VideoMode.cpp ${INCROOT}/VideoMode.hpp ${SRCROOT}/VideoModeImpl.hpp diff --git a/src/SFML/Window/OSX/InputImpl.hpp b/src/SFML/Window/OSX/InputImpl.hpp index 858f5caf..8ddd8efb 100644 --- a/src/SFML/Window/OSX/InputImpl.hpp +++ b/src/SFML/Window/OSX/InputImpl.hpp @@ -114,6 +114,43 @@ public : /// //////////////////////////////////////////////////////////// static void setMousePosition(const Vector2i& position, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isTouchDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/OSX/InputImpl.mm b/src/SFML/Window/OSX/InputImpl.mm index 2639d64f..539b9daa 100644 --- a/src/SFML/Window/OSX/InputImpl.mm +++ b/src/SFML/Window/OSX/InputImpl.mm @@ -178,6 +178,30 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ setMousePosition(sf::Vector2i(p.x, p.y)); } + +//////////////////////////////////////////////////////////// +bool InputImpl::isTouchDown(unsigned int /*finger*/) +{ + // Not applicable + return false; +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) +{ + // Not applicable + return Vector2i(); +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +{ + // Not applicable + return Vector2i(); +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Touch.cpp b/src/SFML/Window/Touch.cpp new file mode 100644 index 00000000..2bdc52f0 --- /dev/null +++ b/src/SFML/Window/Touch.cpp @@ -0,0 +1,54 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without 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 +{ +//////////////////////////////////////////////////////////// +bool Touch::isDown(unsigned int finger) +{ + return priv::InputImpl::isTouchDown(finger); +} + + +//////////////////////////////////////////////////////////// +Vector2i Touch::getPosition(unsigned int finger) +{ + return priv::InputImpl::getTouchPosition(finger); +} + + +//////////////////////////////////////////////////////////// +Vector2i Touch::getPosition(unsigned int finger, const Window& relativeTo) +{ + return priv::InputImpl::getTouchPosition(finger, relativeTo); +} + +} // namespace sf diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp index 63d97379..c0bc1822 100644 --- a/src/SFML/Window/Unix/InputImpl.cpp +++ b/src/SFML/Window/Unix/InputImpl.cpp @@ -288,6 +288,30 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ CloseDisplay(display); } + +//////////////////////////////////////////////////////////// +bool InputImpl::isTouchDown(unsigned int /*finger*/) +{ + // Not applicable + return false; +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) +{ + // Not applicable + return Vector2i(); +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +{ + // Not applicable + return Vector2i(); +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp index 382937fc..a5fbcc88 100644 --- a/src/SFML/Window/Unix/InputImpl.hpp +++ b/src/SFML/Window/Unix/InputImpl.hpp @@ -113,6 +113,43 @@ public : /// //////////////////////////////////////////////////////////// static void setMousePosition(const Vector2i& position, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isTouchDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/Win32/InputImpl.cpp b/src/SFML/Window/Win32/InputImpl.cpp index fafc6848..5bd187a1 100644 --- a/src/SFML/Window/Win32/InputImpl.cpp +++ b/src/SFML/Window/Win32/InputImpl.cpp @@ -220,6 +220,30 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ } } + +//////////////////////////////////////////////////////////// +bool InputImpl::isTouchDown(unsigned int /*finger*/) +{ + // Not applicable + return false; +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) +{ + // Not applicable + return Vector2i(); +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +{ + // Not applicable + return Vector2i(); +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp index ed3be389..a724a66c 100644 --- a/src/SFML/Window/Win32/InputImpl.hpp +++ b/src/SFML/Window/Win32/InputImpl.hpp @@ -113,6 +113,43 @@ public : /// //////////////////////////////////////////////////////////// static void setMousePosition(const Vector2i& position, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isTouchDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/iOS/InputImpl.hpp b/src/SFML/Window/iOS/InputImpl.hpp index ea1f3ee9..066b8818 100644 --- a/src/SFML/Window/iOS/InputImpl.hpp +++ b/src/SFML/Window/iOS/InputImpl.hpp @@ -121,6 +121,43 @@ public : /// //////////////////////////////////////////////////////////// static void setMousePosition(const Vector2i& position, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Check if a touch event is currently down + /// + /// \param finger Finger index + /// + /// \return True if \a finger is currently touching the screen, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isTouchDown(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in desktop coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of a touch in window coordinates + /// + /// This function returns the current touch position + /// in global (desktop) coordinates. + /// + /// \param finger Finger index + /// \param relativeTo Reference window + /// + /// \return Current position of \a finger, or undefined if it's not down + /// + //////////////////////////////////////////////////////////// + static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/iOS/InputImpl.mm b/src/SFML/Window/iOS/InputImpl.mm index 006821e1..35b61e5a 100644 --- a/src/SFML/Window/iOS/InputImpl.mm +++ b/src/SFML/Window/iOS/InputImpl.mm @@ -54,21 +54,15 @@ void InputImpl::setVirtualKeyboardVisible(bool visible) //////////////////////////////////////////////////////////// bool InputImpl::isMouseButtonPressed(Mouse::Button button) { - switch (button) - { - case Mouse::Left: - return getMousePosition() != Vector2i(-1, -1); - - default: - return false; - } + // Not applicable + return false; } //////////////////////////////////////////////////////////// Vector2i InputImpl::getMousePosition() { - return [[SFAppDelegate getInstance] getTouchPosition]; + return Vector2i(0, 0); } @@ -94,6 +88,29 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ // Not applicable } + +//////////////////////////////////////////////////////////// +bool InputImpl::isTouchDown(unsigned int finger) +{ + return [[SFAppDelegate getInstance] getTouchPosition:finger] != Vector2i(-1, -1); +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int finger) +{ + return [[SFAppDelegate getInstance] getTouchPosition:finger]; +} + + +//////////////////////////////////////////////////////////// +Vector2i InputImpl::getTouchPosition(unsigned int finger, const Window& relativeTo) +{ + (void)relativeTo; + + return getTouchPosition(finger); +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/iOS/SFAppDelegate.hpp b/src/SFML/Window/iOS/SFAppDelegate.hpp index db61bc36..77f1a63b 100644 --- a/src/SFML/Window/iOS/SFAppDelegate.hpp +++ b/src/SFML/Window/iOS/SFAppDelegate.hpp @@ -56,36 +56,41 @@ - (void)setVirtualKeyboardVisible:(bool)visible; //////////////////////////////////////////////////////////// -/// \brief Get the current touch position +/// \brief Get the current touch position for a given finger +/// +/// \param index Finger index /// /// \return Current touch position, or (-1, -1) if no touch /// //////////////////////////////////////////////////////////// -- (sf::Vector2i)getTouchPosition; +- (sf::Vector2i)getTouchPosition:(unsigned int)index; //////////////////////////////////////////////////////////// /// \brief Receive an external touch begin notification /// +/// \param index Finger index /// \param position Position of the touch /// //////////////////////////////////////////////////////////// -- (void)notifyTouchBeginAt:(CGPoint)position; +- (void)notifyTouchBegin:(unsigned int)index atPosition:(sf::Vector2i)position; //////////////////////////////////////////////////////////// /// \brief Receive an external touch move notification /// +/// \param index Finger index /// \param position Position of the touch /// //////////////////////////////////////////////////////////// -- (void)notifyTouchMoveAt:(CGPoint)position; +- (void)notifyTouchMove:(unsigned int)index atPosition:(sf::Vector2i)position; //////////////////////////////////////////////////////////// /// \brief Receive an external touch end notification /// +/// \param index Finger index /// \param position Position of the touch /// //////////////////////////////////////////////////////////// -- (void)notifyTouchEndAt:(CGPoint)position; +- (void)notifyTouchEnd:(unsigned int)index atPosition:(sf::Vector2i)position; //////////////////////////////////////////////////////////// /// \brief Receive an external character notification diff --git a/src/SFML/Window/iOS/SFAppDelegate.mm b/src/SFML/Window/iOS/SFAppDelegate.mm index e800b175..f875c6d0 100644 --- a/src/SFML/Window/iOS/SFAppDelegate.mm +++ b/src/SFML/Window/iOS/SFAppDelegate.mm @@ -27,19 +27,22 @@ //////////////////////////////////////////////////////////// #include #include +#include namespace { // Save the global instance of the delegate SFAppDelegate* delegateInstance = NULL; + + // Current touches positions + std::vector touchPositions; } @interface SFAppDelegate() @property (nonatomic) CMMotionManager* motionManager; -@property (nonatomic) sf::Vector2i touchPosition; @end @@ -73,9 +76,6 @@ namespace // Instanciate the motion manager self.motionManager = [[CMMotionManager alloc] init]; - // Initialize the touch position - self.touchPosition = sf::Vector2i(-1, -1); - // Register orientation changes notifications [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object: nil]; @@ -167,15 +167,15 @@ namespace (orientation == UIDeviceOrientationPortraitUpsideDown)) { // Get the new size - CGSize size = [UIScreen mainScreen].bounds.size; + sf::Vector2u size = self.sfWindow->getSize(); if (UIDeviceOrientationIsLandscape(orientation)) - std::swap(size.width, size.height); + std::swap(size.x, size.y); // Send a Resized event to the current window sf::Event event; event.type = sf::Event::Resized; - event.size.width = size.width; - event.size.height = size.height; + event.size.width = size.x; + event.size.height = size.y; sfWindow->pushEvent(event); } } @@ -190,57 +190,72 @@ namespace //////////////////////////////////////////////////////////// -- (sf::Vector2i)getTouchPosition +- (sf::Vector2i)getTouchPosition:(unsigned int)index { - return self.touchPosition; + if (index < touchPositions.size()) + return touchPositions[index]; + else + return sf::Vector2i(-1, -1); } //////////////////////////////////////////////////////////// -- (void)notifyTouchBeginAt:(CGPoint)position +- (void)notifyTouchBegin:(unsigned int)index atPosition:(sf::Vector2i)position; { - self.touchPosition = sf::Vector2i(static_cast(position.x), static_cast(position.y)); + // save the touch position + if (index >= touchPositions.size()) + touchPositions.resize(index + 1, sf::Vector2i(-1, -1)); + touchPositions[index] = position; + // notify the event to the application window if (self.sfWindow) { sf::Event event; - event.type = sf::Event::MouseButtonPressed; - event.mouseButton.x = position.x; - event.mouseButton.y = position.y; - event.mouseButton.button = sf::Mouse::Left; + event.type = sf::Event::TouchBegan; + event.touch.finger = index; + event.touch.x = position.x; + event.touch.y = position.y; sfWindow->pushEvent(event); } } //////////////////////////////////////////////////////////// -- (void)notifyTouchMoveAt:(CGPoint)position +- (void)notifyTouchMove:(unsigned int)index atPosition:(sf::Vector2i)position; { - self.touchPosition = sf::Vector2i(static_cast(position.x), static_cast(position.y)); + // save the touch position + if (index >= touchPositions.size()) + touchPositions.resize(index + 1, sf::Vector2i(-1, -1)); + touchPositions[index] = position; + // notify the event to the application window if (self.sfWindow) { sf::Event event; - event.type = sf::Event::MouseMoved; - event.mouseMove.x = position.x; - event.mouseMove.y = position.y; + event.type = sf::Event::TouchMoved; + event.touch.finger = index; + event.touch.x = position.x; + event.touch.y = position.y; sfWindow->pushEvent(event); } } //////////////////////////////////////////////////////////// -- (void)notifyTouchEndAt:(CGPoint)position +- (void)notifyTouchEnd:(unsigned int)index atPosition:(sf::Vector2i)position; { - self.touchPosition = sf::Vector2i(-1, -1); + // clear the touch position + if (index < touchPositions.size()) + touchPositions[index] = sf::Vector2i(-1, -1); + // notify the event to the application window if (self.sfWindow) { sf::Event event; - event.type = sf::Event::MouseButtonReleased; - event.mouseButton.x = position.x; - event.mouseButton.y = position.y; - event.mouseButton.button = sf::Mouse::Left; + event.type = sf::Event::TouchEnded; + event.touch.finger = index; + event.touch.x = position.x; + event.touch.y = position.y; sfWindow->pushEvent(event); } } diff --git a/src/SFML/Window/iOS/SFView.mm b/src/SFML/Window/iOS/SFView.mm index 4c88da05..bac46c85 100644 --- a/src/SFML/Window/iOS/SFView.mm +++ b/src/SFML/Window/iOS/SFView.mm @@ -32,6 +32,13 @@ #include +@interface SFView() + +@property (nonatomic) NSMutableArray* touches; + +@end + + @implementation SFView @synthesize context; @@ -78,30 +85,70 @@ //////////////////////////////////////////////////////////// - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { - UITouch* touch = [touches anyObject]; - CGPoint position = [touch locationInView:self]; + for (UITouch* touch in touches) + { + // find an empty slot for the new touch + NSUInteger index = [self.touches indexOfObject:[NSNull null]]; + if (index != NSNotFound) + { + [self.touches replaceObjectAtIndex:index withObject:touch]; + } + else + { + [self.touches addObject:touch]; + index = [self.touches count] - 1; + } - [[SFAppDelegate getInstance] notifyTouchBeginAt:position]; + // get the touch position + CGPoint point = [touch locationInView:self]; + sf::Vector2i position(static_cast(point.x), static_cast(point.y)); + + // notify the application delegate + [[SFAppDelegate getInstance] notifyTouchBegin:index atPosition:position]; + } } //////////////////////////////////////////////////////////// - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { - UITouch* touch = [touches anyObject]; - CGPoint position = [touch locationInView:self]; + for (UITouch* touch in touches) + { + // find the touch + NSUInteger index = [self.touches indexOfObject:touch]; + if (index != NSNotFound) + { + // get the touch position + CGPoint point = [touch locationInView:self]; + sf::Vector2i position(static_cast(point.x), static_cast(point.y)); - [[SFAppDelegate getInstance] notifyTouchMoveAt:position]; + // notify the application delegate + [[SFAppDelegate getInstance] notifyTouchMove:index atPosition:position]; + } + } } //////////////////////////////////////////////////////////// - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { - UITouch* touch = [touches anyObject]; - CGPoint position = [touch locationInView:self]; + for (UITouch* touch in touches) + { + // find the touch + NSUInteger index = [self.touches indexOfObject:touch]; + if (index != NSNotFound) + { + // get the touch position + CGPoint point = [touch locationInView:self]; + sf::Vector2i position(static_cast(point.x), static_cast(point.y)); - [[SFAppDelegate getInstance] notifyTouchEndAt:position]; + // notify the application delegate + [[SFAppDelegate getInstance] notifyTouchEnd:index atPosition:position]; + + // remove the touch + [self.touches replaceObjectAtIndex:index withObject:[NSNull null]]; + } + } } @@ -136,6 +183,7 @@ if (self) { self.context = NULL; + self.touches = [NSMutableArray array]; // Configure the EAGL layer CAEAGLLayer* eaglLayer = (CAEAGLLayer*)self.layer; @@ -145,8 +193,9 @@ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; - // Enable user interactions on the view (touch events) + // Enable user interactions on the view (multi-touch events) self.userInteractionEnabled = true; + self.multipleTouchEnabled = true; } return self;