diff options
Diffstat (limited to 'src/input/touch')
18 files changed, 2164 insertions, 0 deletions
diff --git a/src/input/touch/ITouchActionHandler.h b/src/input/touch/ITouchActionHandler.h new file mode 100644 index 0000000000..4a3b5b8321 --- /dev/null +++ b/src/input/touch/ITouchActionHandler.h @@ -0,0 +1,240 @@ +#pragma once +/* + * Copyright (C) 2012-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> + +/*! + * \ingroup touch + * \brief Directions in which a touch can moved + * + * These values can be combined (bitwise OR) to specify multiple directions. + */ +typedef enum { + TouchMoveDirectionNone = 0x0, + TouchMoveDirectionLeft = 0x1, + TouchMoveDirectionRight = 0x2, + TouchMoveDirectionUp = 0x4, + TouchMoveDirectionDown = 0x8 +} TouchMoveDirection; + +/*! + * \ingroup touch + * \brief Interface defining all supported touch action events + */ +class ITouchActionHandler +{ +public: + virtual ~ITouchActionHandler() { } + + /*! + * \brief A touch action has been aborted + */ + virtual void OnTouchAbort() { }; + + /*! + * \brief A single touch has started + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * + * \return True if the event was handled otherwise false + * + * \sa OnSingleTap + */ + virtual bool OnSingleTouchStart(float x, float y) { return true; } + /*! + * \brief A single touch has been held down for a certain amount of time + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * + * \return True if the event was handled otherwise false + * + * \sa OnSingleLongPress + */ + virtual bool OnSingleTouchHold(float x, float y) { return true; } + /*! + * \brief A single touch has moved + * + * \param x The x coordinate (with sub-pixel) of the current touch + * \param y The y coordinate (with sub-pixel) of the current touch + * \param offsetX The covered distance on the x axis (with sub-pixel) + * \param offsetX The covered distance on the y axis (with sub-pixel) + * \param velocityX The velocity of the gesture in x direction (pixels/second) + * \param velocityX The velocity of the gesture in y direction (pixels/second) + * + * \return True if the event was handled otherwise false + * + * \sa OnTouchGesturePan + */ + virtual bool OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) { return true; } + /*! + * \brief A single touch has been lifted + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * + * \return True if the event was handled otherwise false + * + * \sa OnSingleTap + */ + virtual bool OnSingleTouchEnd(float x, float y) { return true; } + + /*! + * \brief An additional touch has been performed + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param pointer The pointer that has performed the touch + * + * \return True if the event was handled otherwise false + */ + virtual bool OnMultiTouchDown(float x, float y, int32_t pointer) { return true; } + /*! + * \brief Multiple simultaneous touches have been held down for a certain amount of time + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param pointers The number of pointers involved (default 2) + * + * \return True if the event was handled otherwise false + */ + virtual bool OnMultiTouchHold(float x, float y, int32_t pointers = 2) { return true; } + /*! + * \brief A touch has moved + * + * \param x The x coordinate (with sub-pixel) of the current touch + * \param y The y coordinate (with sub-pixel) of the current touch + * \param offsetX The covered distance on the x axis (with sub-pixel) + * \param offsetX The covered distance on the y axis (with sub-pixel) + * \param velocityX The velocity of the gesture in x direction (pixels/second) + * \param velocityX The velocity of the gesture in y direction (pixels/second) + * \param pointer The pointer that has performed the touch + * + * \return True if the event was handled otherwise false + */ + virtual bool OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer) { return true; } + /*! + * \brief A touch has been lifted (but there are still active touches) + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param pointer The pointer that has performed the touch + * + * \return True if the event was handled otherwise false + */ + virtual bool OnMultiTouchUp(float x, float y, int32_t pointer) { return true; } + + /*! + * \brief A pan gesture with a single touch has been started + * + * \param x The x coordinate (with sub-pixel) of the initial touch + * \param y The y coordinate (with sub-pixel) of the initial touch + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchGestureStart(float x, float y) { return true; } + /*! + * \brief A pan gesture with a single touch is in progress + * + * \param x The x coordinate (with sub-pixel) of the current touch + * \param y The y coordinate (with sub-pixel) of the current touch + * \param offsetX The covered distance on the x axis (with sub-pixel) + * \param offsetX The covered distance on the y axis (with sub-pixel) + * \param velocityX The velocity of the gesture in x direction (pixels/second) + * \param velocityX The velocity of the gesture in y direction (pixels/second) + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) { return true; } + /*! + * \brief A pan gesture with a single touch has ended + * + * \param x The x coordinate (with sub-pixel) of the current touch + * \param y The y coordinate (with sub-pixel) of the current touch + * \param offsetX The covered distance on the x axis (with sub-pixel) + * \param offsetX The covered distance on the y axis (with sub-pixel) + * \param velocityX The velocity of the gesture in x direction (pixels/second) + * \param velocityX The velocity of the gesture in y direction (pixels/second) + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchGestureEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) { return true; } + + // convenience events + /*! + * \brief A tap with a one or more touches has been performed + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param pointers The number of pointers involved (default 1) + * + * \return True if the event was handled otherwise false + */ + virtual void OnTap(float x, float y, int32_t pointers = 1) { } + /*! + * \brief One or more touches have been held down for a certain amount of time + * + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param pointers The number of pointers involved (default 1) + * + * \return True if the event was handled otherwise false + * + * \sa OnSingleTouchHold + */ + virtual void OnLongPress(float x, float y, int32_t pointers = 1) { } + /*! + * \brief One or more touches has been moved quickly in a single direction in a short time + * + * \param direction The direction (left, right, up, down) of the swipe gesture + * \param xDown The x coordinate (with sub-pixel) of the first touch + * \param yDown The y coordinate (with sub-pixel) of the first touch + * \param xUp The x coordinate (with sub-pixel) of the last touch + * \param yUp The y coordinate (with sub-pixel) of the last touch + * \param velocityX The velocity of the gesture in x direction (pixels/second) + * \param velocityX The velocity of the gesture in y direction (pixels/second) + * \param pointers The number of pointers involved (default 1) + * + * \return True if the event was handled otherwise false + */ + virtual void OnSwipe(TouchMoveDirection direction, float xDown, float yDown, float xUp, float yUp, float velocityX, float velocityY, int32_t pointers = 1) { } + /*! + * \brief Two simultaneous touches have been held down and moved to perform a zooming/pinching gesture + * + * \param centerX The x coordinate (with sub-pixel) of the center of the two touches + * \param centerY The y coordinate (with sub-pixel) of the center of the two touches + * \param zoomFactor The zoom (> 1.0) or pinch (< 1.0) factor of the two touches + * + * \return True if the event was handled otherwise false + */ + virtual void OnZoomPinch(float centerX, float centerY, float zoomFactor) { } + /*! + * \brief Two simultaneous touches have been held down and moved to perform a rotating gesture + * + * \param centerX The x coordinate (with sub-pixel) of the center of the two touches + * \param centerY The y coordinate (with sub-pixel) of the center of the two touches + * \param angle The clockwise angle in degrees of the rotation + * + * \return True if the event was handled otherwise false + */ + virtual void OnRotate(float centerX, float centerY, float angle) { } +};
\ No newline at end of file diff --git a/src/input/touch/ITouchInputHandler.h b/src/input/touch/ITouchInputHandler.h new file mode 100644 index 0000000000..6ea47dbc8d --- /dev/null +++ b/src/input/touch/ITouchInputHandler.h @@ -0,0 +1,104 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> + +#include "input/touch/ITouchInputHandling.h" + +/*! + * \ingroup touch + * \brief Touch input event + */ +typedef enum { + TouchInputAbort, + TouchInputDown, + TouchInputUp, + TouchInputMove +} TouchInput; + +/*! + * \ingroup touch + * \brief Interface (implements ITouchInputHandling) defining methods to handle + * raw touch input events (down, up, move). + * + * This interface should be implemented on platforms only supporting low level + * (raw) touch input events like touch down/up/move and with no gesture + * recognition logic. + */ +class ITouchInputHandler : public ITouchInputHandling +{ +public: + ITouchInputHandler() + : m_dpi(160.0f) + { } + virtual ~ITouchInputHandler() { } + + /*! + * \brief Handle a touch event + * + * Handles the given touch event at the given location. + * This takes into account all the currently active pointers + * which need to be updated before calling this method to + * actually interprete and handle the changes in touch. + * + * \param event The actual touch event (abort, down, up, move) + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param time The time (in nanoseconds) when this touch occured + * \param pointer The number of the touch pointer which caused this event (default 0) + * \param size The size of the touch pointer (with sub-pixel) (default 0.0) + * + * \return True if the event was handled otherwise false. + * + * \sa Update + */ + virtual bool HandleTouchInput(TouchInput event, float x, float y, int64_t time, int32_t pointer = 0, float size = 0.0f) = 0; + + /*! + * \brief Update the coordinates of a pointer + * + * Depending on how a platform handles touch input and provides the necessary events + * this method needs to be called at different times. If there's an event for every + * touch action this method does not need to be called at all. If there's only a + * touch event for the primary pointer (and no special events for any secondary + * pointers in a multi touch gesture) this method should be called for every active + * secondary pointer before calling Handle. + * + * \param pointer The number of the touch pointer which caused this event (default 0) + * \param x The x coordinate (with sub-pixel) of the touch + * \param y The y coordinate (with sub-pixel) of the touch + * \param time The time (in nanoseconds) when this touch occured + * \param size The size of the touch pointer (with sub-pixel) (default 0.0) + * + * \return True if the pointer was updated otherwise false. + * + * \sa Handle + */ + virtual bool UpdateTouchPointer(int32_t pointer, float x, float y, int64_t time, float size = 0.0f) { return false; } + + void SetScreenDPI(float dpi) { if (dpi > 0.0f) m_dpi = dpi; } + +protected: + /*! + * \brief DPI value of the touch screen + */ + float m_dpi; +}; diff --git a/src/input/touch/ITouchInputHandling.cpp b/src/input/touch/ITouchInputHandling.cpp new file mode 100644 index 0000000000..458e66c21d --- /dev/null +++ b/src/input/touch/ITouchInputHandling.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "ITouchInputHandling.h" + +void ITouchInputHandling::RegisterHandler(ITouchActionHandler *touchHandler) +{ + m_handler = touchHandler; +} + +void ITouchInputHandling::UnregisterHandler() +{ + m_handler = NULL; +} + +void ITouchInputHandling::OnTouchAbort() +{ + if (m_handler) + m_handler->OnTouchAbort(); +} + +bool ITouchInputHandling::OnSingleTouchStart(float x, float y) +{ + if (m_handler) + return m_handler->OnSingleTouchStart(x, y); + + return true; +} + +bool ITouchInputHandling::OnSingleTouchHold(float x, float y) +{ + if (m_handler) + return m_handler->OnSingleTouchHold(x, y); + + return true; +} + +bool ITouchInputHandling::OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + if (m_handler) + return m_handler->OnSingleTouchMove(x, y, offsetX, offsetY, velocityX, velocityY); + + return true; +} + +bool ITouchInputHandling::OnSingleTouchEnd(float x, float y) +{ + if (m_handler) + return m_handler->OnSingleTouchEnd(x, y); + + return true; +} + +bool ITouchInputHandling::OnMultiTouchDown(float x, float y, int32_t pointer) +{ + if (m_handler) + return m_handler->OnMultiTouchDown(x, y, pointer); + + return true; +} + +bool ITouchInputHandling::OnMultiTouchHold(float x, float y, int32_t pointers /* = 2 */) +{ + if (m_handler) + return m_handler->OnMultiTouchHold(x, y, pointers); + + return true; +} + +bool ITouchInputHandling::OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer) +{ + if (m_handler) + return m_handler->OnMultiTouchMove(x, y, offsetX, offsetY, velocityX, velocityY, pointer); + + return true; +} + +bool ITouchInputHandling::OnMultiTouchUp(float x, float y, int32_t pointer) +{ + if (m_handler) + return m_handler->OnMultiTouchUp(x, y, pointer); + + return true; +} + +bool ITouchInputHandling::OnTouchGestureStart(float x, float y) +{ + if (m_handler) + return m_handler->OnTouchGestureStart(x, y); + + return true; +} + +bool ITouchInputHandling::OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + if (m_handler) + return m_handler->OnTouchGesturePan(x, y, offsetX, offsetY, velocityX, velocityY); + + return true; +} + +bool ITouchInputHandling::OnTouchGestureEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + if (m_handler) + return m_handler->OnTouchGestureEnd(x, y, offsetX, offsetY, velocityX, velocityY); + + return true; +} + +void ITouchInputHandling::OnTap(float x, float y, int32_t pointers /* = 1 */) +{ + if (m_handler) + m_handler->OnTap(x, y, pointers); +} + +void ITouchInputHandling::OnLongPress(float x, float y, int32_t pointers /* = 1 */) +{ + if (m_handler) + m_handler->OnLongPress(x, y, pointers); +} + +void ITouchInputHandling::OnSwipe(TouchMoveDirection direction, float xDown, float yDown, float xUp, float yUp, float velocityX, float velocityY, int32_t pointers /* = 1 */) +{ + if (m_handler) + m_handler->OnSwipe(direction, xDown, yDown, xUp, yUp, velocityX, velocityY, pointers); +} + +void ITouchInputHandling::OnZoomPinch(float centerX, float centerY, float zoomFactor) +{ + if (m_handler) + m_handler->OnZoomPinch(centerX, centerY, zoomFactor); +} + +void ITouchInputHandling::OnRotate(float centerX, float centerY, float angle) +{ + if (m_handler) + m_handler->OnRotate(centerX, centerY, angle); +} diff --git a/src/input/touch/ITouchInputHandling.h b/src/input/touch/ITouchInputHandling.h new file mode 100644 index 0000000000..f88cf9038b --- /dev/null +++ b/src/input/touch/ITouchInputHandling.h @@ -0,0 +1,87 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> + +#include "input/touch/ITouchActionHandler.h" + +/*! + * \ingroup touch + * \brief Convencience interface implementing ITouchActionHandler with an + * implementation that forwards any ITouchActionHandler-related calls + * to a previously registered ITouchActionHandler + * + * \sa ITouchActionHandler + */ +class ITouchInputHandling : protected ITouchActionHandler +{ +public: + ITouchInputHandling() + : m_handler(NULL) + { } + virtual ~ITouchInputHandling() { } + + /*! + * \brief Register a touch input handler + * + * There can only be one touch input handler. + * + * \param touchHandler An instance of a touch handler implementing the + * ITouchActionHandler interface + * + * \sa UnregisterHandler + */ + void RegisterHandler(ITouchActionHandler *touchHandler); + /*! + * \brief Unregister the previously registered touch handler + * + * \sa RegisterHandler + */ + void UnregisterHandler(); + +protected: + // implementation of ITouchActionHandler + virtual void OnTouchAbort(); + + virtual bool OnSingleTouchStart(float x, float y); + virtual bool OnSingleTouchHold(float x, float y); + virtual bool OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + virtual bool OnSingleTouchEnd(float x, float y); + + virtual bool OnMultiTouchDown(float x, float y, int32_t pointer); + virtual bool OnMultiTouchHold(float x, float y, int32_t pointers = 2); + virtual bool OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer); + virtual bool OnMultiTouchUp(float x, float y, int32_t pointer); + + virtual bool OnTouchGestureStart(float x, float y); + virtual bool OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + virtual bool OnTouchGestureEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + + // convenience events + virtual void OnTap(float x, float y, int32_t pointers = 1); + virtual void OnLongPress(float x, float y, int32_t pointers = 1); + virtual void OnSwipe(TouchMoveDirection direction, float xDown, float yDown, float xUp, float yUp, float velocityX, float velocityY, int32_t pointers = 1); + virtual void OnZoomPinch(float centerX, float centerY, float zoomFactor); + virtual void OnRotate(float centerX, float centerY, float angle); + +private: + ITouchActionHandler *m_handler; +}; diff --git a/src/input/touch/Makefile b/src/input/touch/Makefile new file mode 100644 index 0000000000..6672614b60 --- /dev/null +++ b/src/input/touch/Makefile @@ -0,0 +1,6 @@ +SRCS=ITouchInputHandling.cpp \ + +LIB=input_touch.a + +include ../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/src/input/touch/TouchTypes.h b/src/input/touch/TouchTypes.h new file mode 100644 index 0000000000..b4cc1e3ddb --- /dev/null +++ b/src/input/touch/TouchTypes.h @@ -0,0 +1,120 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "utils/Vector.h" + +/*! + * \ingroup touch + * \brief A class representing a touch consisting of an x and y coordinate and + * a time + */ +class Touch : public CVector +{ +public: + Touch() { reset(); } + virtual ~Touch() { } + + /*! + * \brief Resets the x/y coordinates and the time + */ + virtual void reset() { CVector::reset(); time = -1; } + + /*! + * \brief Checks if the touch is valid i.e. if the x/y coordinates and the + * time are >= 0 + * + * \return True if the touch is valid otherwise false + */ + bool valid() const { return x >= 0.0f && y >= 0.0f && time >= 0; } + + /*! + * \brief Copies the x/y coordinates and the time from the given touch + * + * \param other Touch to copy x/y coordinates and time from + */ + void copy(const Touch &other) { x = other.x; y = other.y; time = other.time; } + + int64_t time; // in nanoseconds +}; + +/*! + * \ingroup touch + * \brief A class representing a touch pointer interaction consisting of an + * down touch, the last touch and the current touch. + */ +class Pointer +{ +public: + Pointer() { reset(); } + + /*! + * \brief Resets the pointer and all its touches + */ + void reset() { down.reset(); last.reset(); moving = false; size = 0.0f; } + + /*! + * \brief Checks if the "down" touch is valid + * + * \return True if the "down" touch is valid otherwise false + */ + bool valid() const { return down.valid(); } + + /*! + * \brief Calculates the velocity in x/y direction using the "down" and + * either the "last" or "current" touch + * + * \param velocityX Placeholder for velocity in x direction + * \param velocityY Placeholder for velocity in y direction + * \param fromLast Whether to calculate the velocity with the "last" or + * the "current" touch + * + * \return True if the velocity is valid otherwise false + */ + bool velocity(float &velocityX, float &velocityY, bool fromLast = true) const + { + int64_t fromTime = last.time; + float fromX = last.x; + float fromY = last.y; + if (!fromLast) + { + fromTime = down.time; + fromX = down.x; + fromY = down.y; + } + + velocityX = 0.0f; // number of pixels per second + velocityY = 0.0f; // number of pixels per second + + int64_t timeDiff = current.time - fromTime; + if (timeDiff <= 0) + return false; + + velocityX = ((current.x - fromX) * 1000000000) / timeDiff; + velocityY = ((current.y - fromY) * 1000000000) / timeDiff; + return true; + } + + Touch down; + Touch last; + Touch current; + bool moving; + float size; +};
\ No newline at end of file diff --git a/src/input/touch/generic/GenericTouchActionHandler.cpp b/src/input/touch/generic/GenericTouchActionHandler.cpp new file mode 100644 index 0000000000..db57c987a0 --- /dev/null +++ b/src/input/touch/generic/GenericTouchActionHandler.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GenericTouchActionHandler.h" +#include "ApplicationMessenger.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/Key.h" +#include "windowing/WinEvents.h" + +CGenericTouchActionHandler &CGenericTouchActionHandler::Get() +{ + static CGenericTouchActionHandler sTouchAction; + return sTouchAction; +} + +void CGenericTouchActionHandler::OnTouchAbort() +{ } + +bool CGenericTouchActionHandler::OnSingleTouchStart(float x, float y) +{ + focusControl(x, y); + + return true; +} + +bool CGenericTouchActionHandler::OnSingleTouchHold(float x, float y) +{ + return true; +} + +bool CGenericTouchActionHandler::OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + return true; +} + +bool CGenericTouchActionHandler::OnSingleTouchEnd(float x, float y) +{ + return true; +} + +bool CGenericTouchActionHandler::OnMultiTouchDown(float x, float y, int32_t pointer) +{ + return true; +} + +bool CGenericTouchActionHandler::OnMultiTouchHold(float x, float y, int32_t pointers /* = 2 */) +{ + return true; +} + +bool CGenericTouchActionHandler::OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer) +{ + return true; +} + +bool CGenericTouchActionHandler::OnMultiTouchUp(float x, float y, int32_t pointer) +{ + return true; +} + +bool CGenericTouchActionHandler::OnTouchGestureStart(float x, float y) +{ + sendEvent(ACTION_GESTURE_BEGIN, x, y, 0.0f, 0.0f); + + return true; +} + +bool CGenericTouchActionHandler::OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + sendEvent(ACTION_GESTURE_PAN, x, y, offsetX, offsetY); + + return true; +} + +bool CGenericTouchActionHandler::OnTouchGestureEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) +{ + sendEvent(ACTION_GESTURE_END, velocityX, velocityY, x, y); + + return true; +} + +void CGenericTouchActionHandler::OnTap(float x, float y, int32_t pointers /* = 1 */) +{ + if (pointers <= 0 || pointers > 10) + return; + + sendEvent(ACTION_TOUCH_TAP, (uint16_t)x, (uint16_t)y, 0.0f, 0.0f, pointers); +} + +void CGenericTouchActionHandler::OnLongPress(float x, float y, int32_t pointers /* = 1 */) +{ + if (pointers <= 0 || pointers > 10) + return; + + sendEvent(ACTION_TOUCH_LONGPRESS, (uint16_t)x, (uint16_t)y, 0.0f, 0.0f, pointers); +} + +void CGenericTouchActionHandler::OnSwipe(TouchMoveDirection direction, float xDown, float yDown, float xUp, float yUp, float velocityX, float velocityY, int32_t pointers /* = 1 */) +{ + if (pointers <= 0 || pointers > 10) + return; + + int actionId = 0; + if (direction == TouchMoveDirectionLeft) + actionId = ACTION_GESTURE_SWIPE_LEFT; + else if (direction == TouchMoveDirectionRight) + actionId = ACTION_GESTURE_SWIPE_RIGHT; + else if (direction == TouchMoveDirectionUp) + actionId = ACTION_GESTURE_SWIPE_UP; + else if (direction == TouchMoveDirectionDown) + actionId = ACTION_GESTURE_SWIPE_DOWN; + else + return; + + sendEvent(actionId, xUp, yUp, velocityX, velocityY, pointers); +} + +void CGenericTouchActionHandler::OnZoomPinch(float centerX, float centerY, float zoomFactor) +{ + sendEvent(ACTION_GESTURE_ZOOM, centerX, centerY, zoomFactor, 0.0f); +} + +void CGenericTouchActionHandler::OnRotate(float centerX, float centerY, float angle) +{ + sendEvent(ACTION_GESTURE_ROTATE, centerX, centerY, angle, 0.0f); +} + +int CGenericTouchActionHandler::QuerySupportedGestures(float x, float y) +{ + CGUIMessage msg(GUI_MSG_GESTURE_NOTIFY, 0, 0, (int)x, (int)y); + if (!g_windowManager.SendMessage(msg)) + return 0; + + return msg.GetParam1(); +} + +void CGenericTouchActionHandler::touch(uint8_t type, uint8_t button, uint16_t x, uint16_t y) +{ + XBMC_Event newEvent; + memset(&newEvent, 0, sizeof(newEvent)); + + newEvent.type = type; + newEvent.button.type = type; + newEvent.button.button = button; + newEvent.button.x = x; + newEvent.button.y = y; + + CWinEvents::MessagePush(&newEvent); +} + +void CGenericTouchActionHandler::sendEvent(int actionId, float x, float y, float x2 /* = 0.0f */, float y2 /* = 0.0f */, int pointers /* = 1 */) +{ + XBMC_Event newEvent; + memset(&newEvent, 0, sizeof(newEvent)); + + newEvent.type = XBMC_TOUCH; + newEvent.touch.type = XBMC_TOUCH; + newEvent.touch.action = actionId; + newEvent.touch.x = x; + newEvent.touch.y = y; + newEvent.touch.x2 = x2; + newEvent.touch.y2 = y2; + newEvent.touch.pointers = pointers; + + CWinEvents::MessagePush(&newEvent); +} + +void CGenericTouchActionHandler::focusControl(float x, float y) +{ + XBMC_Event newEvent; + memset(&newEvent, 0, sizeof(newEvent)); + + newEvent.type = XBMC_SETFOCUS; + newEvent.focus.type = XBMC_SETFOCUS; + newEvent.focus.x = (uint16_t)x; + newEvent.focus.y = (uint16_t)y; + + CWinEvents::MessagePush(&newEvent); +} diff --git a/src/input/touch/generic/GenericTouchActionHandler.h b/src/input/touch/generic/GenericTouchActionHandler.h new file mode 100644 index 0000000000..b4917b89f2 --- /dev/null +++ b/src/input/touch/generic/GenericTouchActionHandler.h @@ -0,0 +1,83 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "input/touch/ITouchActionHandler.h" + +/*! + * \ingroup touch_generic + * \brief Generic implementation of ITouchActionHandler to translate + * touch actions into XBMC specific and mappable actions. + * + * \sa ITouchActionHandler + */ +class CGenericTouchActionHandler : public ITouchActionHandler +{ +public: + /*! + \brief Get an instance of the touch input manager + */ + static CGenericTouchActionHandler &Get(); + + // implementation of ITouchActionHandler + virtual void OnTouchAbort(); + + virtual bool OnSingleTouchStart(float x, float y); + virtual bool OnSingleTouchHold(float x, float y); + virtual bool OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + virtual bool OnSingleTouchEnd(float x, float y); + + virtual bool OnMultiTouchDown(float x, float y, int32_t pointer); + virtual bool OnMultiTouchHold(float x, float y, int32_t pointers = 2); + virtual bool OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer); + virtual bool OnMultiTouchUp(float x, float y, int32_t pointer); + + virtual bool OnTouchGestureStart(float x, float y); + virtual bool OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + virtual bool OnTouchGestureEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY); + + // convenience events + virtual void OnTap(float x, float y, int32_t pointers = 1); + virtual void OnLongPress(float x, float y, int32_t pointers = 1); + virtual void OnSwipe(TouchMoveDirection direction, float xDown, float yDown, float xUp, float yUp, float velocityX, float velocityY, int32_t pointers = 1); + virtual void OnZoomPinch(float centerX, float centerY, float zoomFactor); + virtual void OnRotate(float centerX, float centerY, float angle); + + /*! + \brief Asks the control at the given coordinates for a list of the supported gestures. + + \param x The x coordinate (with sub-pixel) of the touch + \param y The y coordinate (with sub-pixel) of the touch + + \return EVENT_RESULT value of bitwise ORed gestures. + */ + int QuerySupportedGestures(float x, float y); + +private: + // private construction, and no assignements; use the provided singleton methods + CGenericTouchActionHandler() { } + CGenericTouchActionHandler(const CGenericTouchActionHandler&); + CGenericTouchActionHandler const& operator=(CGenericTouchActionHandler const&); + virtual ~CGenericTouchActionHandler() { } + + void touch(uint8_t type, uint8_t button, uint16_t x, uint16_t y); + void sendEvent(int actionId, float x, float y, float x2 = 0.0f, float y2 = 0.0f, int pointers = 1); + void focusControl(float x, float y); +}; diff --git a/src/input/touch/generic/GenericTouchInputHandler.cpp b/src/input/touch/generic/GenericTouchInputHandler.cpp new file mode 100644 index 0000000000..4c91563998 --- /dev/null +++ b/src/input/touch/generic/GenericTouchInputHandler.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2012-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <math.h> + +#include "GenericTouchInputHandler.h" +#include "input/touch/generic/GenericTouchPinchDetector.h" +#include "input/touch/generic/GenericTouchRotateDetector.h" +#include "input/touch/generic/GenericTouchSwipeDetector.h" +#include "threads/SingleLock.h" +#include "utils/log.h" + +#define TOUCH_HOLD_TIMEOUT 1000 +CGenericTouchInputHandler::CGenericTouchInputHandler() + : m_gestureState(TouchGestureUnknown), + m_gestureStateOld(TouchGestureUnknown) +{ + m_holdTimer = new CTimer(this); +} + +CGenericTouchInputHandler::~CGenericTouchInputHandler() +{ + delete m_holdTimer; + + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + delete (*detector); + m_detectors.clear(); +} + +CGenericTouchInputHandler &CGenericTouchInputHandler::Get() +{ + static CGenericTouchInputHandler sTouchInput; + return sTouchInput; +} + +bool CGenericTouchInputHandler::HandleTouchInput(TouchInput event, float x, float y, int64_t time, int32_t pointer /* = 0 */, float size /* = 0.0f */) +{ + if (time < 0 || pointer < 0 || pointer >= TOUCH_MAX_POINTERS) + return false; + + CSingleLock lock(m_critical); + + bool result = true; + + m_pointers[pointer].current.x = x; + m_pointers[pointer].current.y = y; + m_pointers[pointer].current.time = time; + + switch (event) + { + case TouchInputAbort: + { + triggerDetectors(event, pointer); + + setGestureState(TouchGestureUnknown); + for (unsigned int pIndex = 0; pIndex < TOUCH_MAX_POINTERS; pIndex++) + m_pointers[pIndex].reset(); + + OnTouchAbort(); + break; + } + + case TouchInputDown: + { + m_pointers[pointer].down.x = x; + m_pointers[pointer].down.y = y; + m_pointers[pointer].down.time = time; + m_pointers[pointer].moving = false; + m_pointers[pointer].size = size; + + // If this is the down event of the primary pointer + // we start by assuming that it's a single touch + if (pointer == 0) + { + // create new gesture detectors + m_detectors.insert(new CGenericTouchSwipeDetector(this, m_dpi)); + m_detectors.insert(new CGenericTouchPinchDetector(this, m_dpi)); + m_detectors.insert(new CGenericTouchRotateDetector(this, m_dpi)); + triggerDetectors(event, pointer); + + setGestureState(TouchGestureSingleTouch); + result = OnSingleTouchStart(x, y); + + m_holdTimer->Start(TOUCH_HOLD_TIMEOUT); + } + // Otherwise it's the down event of another pointer + else + { + triggerDetectors(event, pointer); + + // If we so far assumed single touch or still have the primary + // pointer of a previous multi touch pressed down, we can update to multi touch + if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold || + m_gestureState == TouchGestureMultiTouchDone) + { + result = OnMultiTouchDown(x, y, pointer); + m_holdTimer->Stop(true); + + if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold) + m_holdTimer->Start(TOUCH_HOLD_TIMEOUT); + + setGestureState(TouchGestureMultiTouchStart); + } + // Otherwise we should ignore this pointer + else + { + m_pointers[pointer].reset(); + break; + } + } + return result; + } + + case TouchInputUp: + { + // unexpected event => abort + if (!m_pointers[pointer].valid() || + m_gestureState == TouchGestureUnknown) + break; + + triggerDetectors(event, pointer); + + m_holdTimer->Stop(false); + + // Just a single tap with a pointer + if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold) + { + result = OnSingleTouchEnd(x, y); + + if (m_gestureState == TouchGestureSingleTouch) + OnTap(x, y, 1); + } + // A pan gesture started with a single pointer (ignoring any other pointers) + else if (m_gestureState == TouchGesturePan) + { + float velocityX = 0.0f; // number of pixels per second + float velocityY = 0.0f; // number of pixels per second + m_pointers[pointer].velocity(velocityX, velocityY, false); + + result = OnTouchGestureEnd(x, y, + x - m_pointers[pointer].down.x, y - m_pointers[pointer].down.y, + velocityX, velocityY); + } + // we are in multi-touch + else + result = OnMultiTouchUp(x, y, pointer); + + // If we were in multi touch mode and lifted one pointer + // we can go into the TouchGestureMultiTouchDone state which will allow + // the user to go back into multi touch mode without lifting the primary pointer + if (m_gestureState == TouchGestureMultiTouchStart || m_gestureState == TouchGestureMultiTouchHold || m_gestureState == TouchGestureMultiTouch) + { + setGestureState(TouchGestureMultiTouchDone); + + // after lifting the primary pointer, the secondary pointer will + // become the primary pointer in the next event + if (pointer == 0) + { + m_pointers[0] = m_pointers[1]; + pointer = 1; + } + } + // Otherwise abort + else + { + if (m_gestureState == TouchGestureMultiTouchDone) + { + float velocityX = 0.0f; // number of pixels per second + float velocityY = 0.0f; // number of pixels per second + m_pointers[pointer].velocity(velocityX, velocityY, false); + + result = OnTouchGestureEnd(x, y, + x - m_pointers[pointer].down.x, y - m_pointers[pointer].down.y, + velocityX, velocityY); + + // if neither of the two pointers moved we have a single tap with multiple pointers + if (m_gestureStateOld != TouchGestureMultiTouchHold && m_gestureStateOld != TouchGestureMultiTouch) + OnTap(fabs((m_pointers[0].down.x + m_pointers[1].down.x) / 2), + fabs((m_pointers[0].down.y + m_pointers[1].down.y) / 2), + 2); + } + + setGestureState(TouchGestureUnknown); + m_pointers[pointer].reset(); + } + + return result; + } + + case TouchInputMove: + { + // unexpected event => abort + if (!m_pointers[pointer].valid() || + m_gestureState == TouchGestureUnknown || + m_gestureState == TouchGestureMultiTouchDone) + break; + + bool moving = false; + for (unsigned int index = 0; index < TOUCH_MAX_POINTERS; index++) + { + if (m_pointers[index].valid() && m_pointers[index].moving) + { + moving = true; + break; + } + } + + if (moving) + { + m_holdTimer->Stop(); + + // the touch is moving so we start a gesture + if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureMultiTouchStart) + result = OnTouchGestureStart(m_pointers[pointer].down.x, m_pointers[pointer].down.y); + } + + triggerDetectors(event, pointer); + + if (m_gestureState == TouchGestureSingleTouch) + { + // Check if the touch has moved far enough to count as movement + if (!m_pointers[pointer].moving) + break; + + m_pointers[pointer].last.copy(m_pointers[pointer].down); + setGestureState(TouchGesturePan); + } + else if (m_gestureState == TouchGestureMultiTouchStart) + { + setGestureState(TouchGestureMultiTouch); + + // set the starting point + saveLastTouch(); + } + + float offsetX = x - m_pointers[pointer].last.x; + float offsetY = y - m_pointers[pointer].last.y; + float velocityX = 0.0f; // number of pixels per second + float velocityY = 0.0f; // number of pixels per second + m_pointers[pointer].velocity(velocityX, velocityY); + + if (m_pointers[pointer].moving && + (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold || m_gestureState == TouchGesturePan)) + result = OnSingleTouchMove(x, y, offsetX, offsetY, velocityX, velocityY); + + // Let's see if we have a pan gesture (i.e. the primary and only pointer moving) + if (m_gestureState == TouchGesturePan) + { + result = OnTouchGesturePan(x, y, offsetX, offsetY, velocityX, velocityY); + + m_pointers[pointer].last.x = x; + m_pointers[pointer].last.y = y; + } + else if (m_gestureState == TouchGestureMultiTouch) + { + if (moving) + result = OnMultiTouchMove(x, y,offsetX, offsetY, velocityX, velocityY, pointer); + } + else + break; + + return result; + } + + default: + CLog::Log(LOGDEBUG, "CGenericTouchInputHandler: unknown TouchInput"); + break; + } + + return false; +} + +bool CGenericTouchInputHandler::UpdateTouchPointer(int32_t pointer, float x, float y, int64_t time, float size /* = 0.0f */) +{ + if (pointer < 0 || pointer >= TOUCH_MAX_POINTERS) + return false; + + CSingleLock lock(m_critical); + + m_pointers[pointer].last.copy(m_pointers[pointer].current); + + m_pointers[pointer].current.x = x; + m_pointers[pointer].current.y = y; + m_pointers[pointer].current.time = time; + if (size > 0.0f) + m_pointers[pointer].size = size; + + // calculate whether the pointer has moved at all + if (!m_pointers[pointer].moving) + { + CVector down = m_pointers[pointer].down; + CVector current = m_pointers[pointer].current; + CVector distance = down - current; + + if (distance.length() > m_pointers[pointer].size) + m_pointers[pointer].moving = true; + } + + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + (*detector)->OnTouchUpdate(pointer, m_pointers[pointer]); + + return true; +} + +void CGenericTouchInputHandler::saveLastTouch() +{ + for (unsigned int pointer = 0; pointer < TOUCH_MAX_POINTERS; pointer++) + m_pointers[pointer].last.copy(m_pointers[pointer].current); +} + +void CGenericTouchInputHandler::OnTimeout() +{ + CSingleLock lock(m_critical); + + switch (m_gestureState) + { + case TouchGestureSingleTouch: + setGestureState(TouchGestureSingleTouchHold); + + OnSingleTouchHold(m_pointers[0].down.x, m_pointers[0].down.y); + OnLongPress(m_pointers[0].down.x, m_pointers[0].down.y, 1); + break; + + case TouchGestureMultiTouchStart: + if (!m_pointers[0].moving && !m_pointers[1].moving) + { + setGestureState(TouchGestureMultiTouchHold); + + OnMultiTouchHold(m_pointers[0].down.x, m_pointers[0].down.y); + OnLongPress(fabs((m_pointers[0].down.x + m_pointers[1].down.x) / 2), + fabs((m_pointers[0].down.y + m_pointers[1].down.y) / 2), + 2); + } + break; + + default: + break; + } +} + +void CGenericTouchInputHandler::triggerDetectors(TouchInput event, int32_t pointer) +{ + switch (event) + { + case TouchInputAbort: + { + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + delete (*detector); + m_detectors.clear(); + break; + } + + case TouchInputDown: + { + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + (*detector)->OnTouchDown(pointer, m_pointers[pointer]); + break; + } + + case TouchInputUp: + { + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + (*detector)->OnTouchUp(pointer, m_pointers[pointer]); + break; + } + + case TouchInputMove: + { + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + (*detector)->OnTouchMove(pointer, m_pointers[pointer]); + break; + } + + default: + return; + } + + std::set<IGenericTouchGestureDetector*> finishedDetectors; + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = m_detectors.begin(); detector != m_detectors.end(); detector++) + { + if ((*detector)->IsDone()) + finishedDetectors.insert(*detector); + } + + for (std::set<IGenericTouchGestureDetector*>::const_iterator detector = finishedDetectors.begin(); detector != finishedDetectors.end(); detector++) + m_detectors.erase(*detector); +} diff --git a/src/input/touch/generic/GenericTouchInputHandler.h b/src/input/touch/generic/GenericTouchInputHandler.h new file mode 100644 index 0000000000..df0cc679aa --- /dev/null +++ b/src/input/touch/generic/GenericTouchInputHandler.h @@ -0,0 +1,96 @@ +#pragma once +/* + * Copyright (C) 2012-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <set> + +#include "input/touch/ITouchInputHandler.h" +#include "input/touch/TouchTypes.h" +#include "threads/CriticalSection.h" +#include "threads/Timer.h" + +#define TOUCH_MAX_POINTERS 2 + +class IGenericTouchGestureDetector; + +/*! + * \ingroup touch_generic + * \brief Generic implementation of ITouchInputHandler to handle low level (raw) + * touch events and translate them into touch actions which are passed + * on to the registered ITouchActionHandler implementation. + * + * The generic implementation supports single a double touch and hold + * actions and basic gesture recognition for panning, swiping, pinching/zooming + * and rotating. + * + * \sa ITouchInputHandler + */ +class CGenericTouchInputHandler : public ITouchInputHandler, private ITimerCallback +{ +public: + /*! + \brief Get an instance of the touch input manager + */ + static CGenericTouchInputHandler &Get(); + + // implementation of ITouchInputHandler + virtual bool HandleTouchInput(TouchInput event, float x, float y, int64_t time, int32_t pointer = 0, float size = 0.0f); + virtual bool UpdateTouchPointer(int32_t pointer, float x, float y, int64_t time, float size = 0.0f); + +private: + // private construction, and no assignements; use the provided singleton methods + CGenericTouchInputHandler(); + CGenericTouchInputHandler(const CGenericTouchInputHandler&); + CGenericTouchInputHandler const& operator=(CGenericTouchInputHandler const&); + virtual ~CGenericTouchInputHandler(); + + typedef enum { + TouchGestureUnknown = 0, + // only primary pointer active but stationary so far + TouchGestureSingleTouch, + // primary pointer active but stationary for a certain time + TouchGestureSingleTouchHold, + // primary pointer moving + TouchGesturePan, + // at least two pointers active but stationary so far + TouchGestureMultiTouchStart, + // at least two pointers active but stationary for a certain time + TouchGestureMultiTouchHold, + // at least two pointers active and moving + TouchGestureMultiTouch, + // all but primary pointer have been lifted + TouchGestureMultiTouchDone + } TouchGestureState; + + // implementation of ITimerCallback + virtual void OnTimeout(); + + void saveLastTouch(); + void setGestureState(TouchGestureState gestureState) { m_gestureStateOld = m_gestureState; m_gestureState = gestureState; } + void triggerDetectors(TouchInput event, int32_t pointer); + + CCriticalSection m_critical; + CTimer *m_holdTimer; + Pointer m_pointers[TOUCH_MAX_POINTERS]; + std::set<IGenericTouchGestureDetector*> m_detectors; + + TouchGestureState m_gestureState; + TouchGestureState m_gestureStateOld; +}; diff --git a/src/input/touch/generic/GenericTouchPinchDetector.cpp b/src/input/touch/generic/GenericTouchPinchDetector.cpp new file mode 100644 index 0000000000..8c3d004b38 --- /dev/null +++ b/src/input/touch/generic/GenericTouchPinchDetector.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GenericTouchPinchDetector.h" + +bool CGenericTouchPinchDetector::OnTouchDown(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + m_pointers[index] = pointer; + return true; +} + +bool CGenericTouchPinchDetector::OnTouchUp(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + // after lifting the primary pointer, the secondary pointer will + // become the primary pointer in the next event + if (index == 0) + { + m_pointers[0] = m_pointers[1]; + index = 1; + } + + m_pointers[index].reset(); + + if (!m_pointers[0].valid() && !m_pointers[1].valid()) + m_done = true; + + return true; +} + +bool CGenericTouchPinchDetector::OnTouchMove(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + // update the internal pointers + m_pointers[index] = pointer; + + Pointer& primaryPointer = m_pointers[0]; + Pointer& secondaryPointer = m_pointers[1]; + + if (!primaryPointer.valid() || !secondaryPointer.valid() || + (!primaryPointer.moving && !secondaryPointer.moving)) + return false; + + // calculate zoom/pinch + CVector primary = primaryPointer.down; + CVector secondary = secondaryPointer.down; + CVector diagonal = primary - secondary; + + float baseDiffLength = diagonal.length(); + if (baseDiffLength != 0.0f) + { + CVector primaryNow = primaryPointer.current; + CVector secondaryNow = secondaryPointer.current; + CVector diagonalNow = primaryNow - secondaryNow; + float curDiffLength = diagonalNow.length(); + + float centerX = (primary.x + secondary.x) / 2; + float centerY = (primary.y + secondary.y) / 2; + + float zoom = curDiffLength / baseDiffLength; + + OnZoomPinch(centerX, centerY, zoom); + } + + return true; +} diff --git a/src/input/touch/generic/GenericTouchPinchDetector.h b/src/input/touch/generic/GenericTouchPinchDetector.h new file mode 100644 index 0000000000..6bddf8386b --- /dev/null +++ b/src/input/touch/generic/GenericTouchPinchDetector.h @@ -0,0 +1,42 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "input/touch/generic/IGenericTouchGestureDetector.h" + +/*! + * \ingroup touch_generic + * \brief Implementation of IGenericTouchGestureDetector to detect pinch/zoom + * gestures with at least two active touch pointers. + * + * \sa IGenericTouchGestureDetector + */ +class CGenericTouchPinchDetector : public IGenericTouchGestureDetector +{ +public: + CGenericTouchPinchDetector(ITouchActionHandler *handler, float dpi) + : IGenericTouchGestureDetector(handler, dpi) + { } + virtual ~CGenericTouchPinchDetector() { } + + virtual bool OnTouchDown(unsigned int index, const Pointer &pointer); + virtual bool OnTouchUp(unsigned int index, const Pointer &pointer); + virtual bool OnTouchMove(unsigned int index, const Pointer &pointer); +}; diff --git a/src/input/touch/generic/GenericTouchRotateDetector.cpp b/src/input/touch/generic/GenericTouchRotateDetector.cpp new file mode 100644 index 0000000000..6462e06c0d --- /dev/null +++ b/src/input/touch/generic/GenericTouchRotateDetector.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <math.h> + +#include "GenericTouchRotateDetector.h" + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795028842 +#endif + +CGenericTouchRotateDetector::CGenericTouchRotateDetector(ITouchActionHandler *handler, float dpi) + : IGenericTouchGestureDetector(handler, dpi), + m_angle(0.0f) +{ } + +bool CGenericTouchRotateDetector::OnTouchDown(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + m_pointers[index] = pointer; + m_angle = 0.0f; + return true; +} + +bool CGenericTouchRotateDetector::OnTouchUp(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + // after lifting the primary pointer, the secondary pointer will + // become the primary pointer in the next event + if (index == 0) + { + m_pointers[0] = m_pointers[1]; + index = 1; + } + + m_pointers[index].reset(); + + if (!m_pointers[0].valid() && !m_pointers[1].valid()) + m_done = true; + + return true; +} + +bool CGenericTouchRotateDetector::OnTouchMove(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + // update the internal pointers + m_pointers[index] = pointer; + + Pointer& primaryPointer = m_pointers[0]; + Pointer& secondaryPointer = m_pointers[1]; + + if (!primaryPointer.valid() || !secondaryPointer.valid() || + (!primaryPointer.moving && !secondaryPointer.moving)) + return false; + + CVector last = primaryPointer.last - secondaryPointer.last; + CVector current = primaryPointer.current - secondaryPointer.current; + + float length = last.length() * current.length(); + if (length != 0.0f) + { + float centerX = (primaryPointer.current.x + secondaryPointer.current.x) / 2; + float centerY = (primaryPointer.current.y + secondaryPointer.current.y) / 2; + float scalar = last.scalar(current); + float angle = acos(scalar / length) * 180.0f / M_PI; + + // make sure the result of acos is a valid number + if (angle == angle) + { + // calculate the direction of the rotation using the + // z-component of the cross-product of last and current + float direction = last.x * current.y - current.x * last.y; + if (direction < 0.0f) + m_angle -= angle; + else + m_angle += angle; + + OnRotate(centerX, centerY, m_angle); + } + } + + return true; +} + +bool CGenericTouchRotateDetector::OnTouchUpdate(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + // update the internal pointers + m_pointers[index] = pointer; + return true; +} diff --git a/src/input/touch/generic/GenericTouchRotateDetector.h b/src/input/touch/generic/GenericTouchRotateDetector.h new file mode 100644 index 0000000000..31e15565a5 --- /dev/null +++ b/src/input/touch/generic/GenericTouchRotateDetector.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "input/touch/generic/IGenericTouchGestureDetector.h" + +/*! + * \ingroup touch_generic + * \brief Implementation of IGenericTouchGestureDetector to detect rotation + * gestures with at least two active touch pointers. + * + * \sa IGenericTouchGestureDetector + */ +class CGenericTouchRotateDetector : public IGenericTouchGestureDetector +{ +public: + CGenericTouchRotateDetector(ITouchActionHandler *handler, float dpi); + virtual ~CGenericTouchRotateDetector() { } + + virtual bool OnTouchDown(unsigned int index, const Pointer &pointer); + virtual bool OnTouchUp(unsigned int index, const Pointer &pointer); + virtual bool OnTouchMove(unsigned int index, const Pointer &pointer); + virtual bool OnTouchUpdate(unsigned int index, const Pointer &pointer); + +private: + /*! + * \brief Angle of the detected rotation + */ + float m_angle; +}; diff --git a/src/input/touch/generic/GenericTouchSwipeDetector.cpp b/src/input/touch/generic/GenericTouchSwipeDetector.cpp new file mode 100644 index 0000000000..2b792724c3 --- /dev/null +++ b/src/input/touch/generic/GenericTouchSwipeDetector.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _USE_MATH_DEFINES +#define _USE_MATH_DEFINES +#endif +#include <math.h> +#include <stdlib.h> + +#include "GenericTouchSwipeDetector.h" + +// maximum time between touch down and up (in nanoseconds) +#define SWIPE_MAX_TIME 500000000 +// maxmium swipe distance between touch down and up (in multiples of screen DPI) +#define SWIPE_MIN_DISTANCE 0.5f +// original maximum variance of the touch movement +#define SWIPE_MAX_VARIANCE 0.2f +// tangens of the maximum angle (20 degrees) the touch movement may vary in a +// direction perpendicular to the swipe direction (in radians) +// => tan(20 deg) = tan(20 * M_PI / 180) +#define SWIPE_MAX_VARIANCE_ANGLE 0.36397023f + +CGenericTouchSwipeDetector::CGenericTouchSwipeDetector(ITouchActionHandler *handler, float dpi) + : IGenericTouchGestureDetector(handler, dpi), + m_directions(TouchMoveDirectionLeft | TouchMoveDirectionRight | TouchMoveDirectionUp | TouchMoveDirectionDown), + m_swipeDetected(false), m_size(0) +{ } + +bool CGenericTouchSwipeDetector::OnTouchDown(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + m_size += 1; + if (m_size > 1) + return true; + + // reset all values + m_done = false; + m_swipeDetected = false; + m_directions = TouchMoveDirectionLeft | TouchMoveDirectionRight | TouchMoveDirectionUp | TouchMoveDirectionDown; + + return true; +} + +bool CGenericTouchSwipeDetector::OnTouchUp(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + m_size -= 1; + if (m_done) + return false; + + m_done = true; + + // check if a swipe has been detected and if it has a valid direction + if (!m_swipeDetected || m_directions == TouchMoveDirectionNone) + return false; + + // check if the swipe has been performed in the proper time span + if ((pointer.current.time - pointer.down.time) > SWIPE_MAX_TIME) + return false; + + // calculate the velocity of the swipe + float velocityX = 0.0f; // number of pixels per second + float velocityY = 0.0f; // number of pixels per second + pointer.velocity(velocityX, velocityY, false); + + // call the OnSwipe() callback + OnSwipe((TouchMoveDirection)m_directions, pointer.down.x, pointer.down.y, pointer.current.x, pointer.current.y, velocityX, velocityY, m_size + 1); + return true; +} + +bool CGenericTouchSwipeDetector::OnTouchMove(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + // only handle swipes of moved pointers + if (index >= m_size || m_done || !pointer.moving) + return false; + + float deltaXmovement = pointer.current.x - pointer.last.x; + float deltaYmovement = pointer.current.y - pointer.last.y; + + if (deltaXmovement > 0.0f) + m_directions &= ~TouchMoveDirectionLeft; + else if (deltaXmovement < 0.0f) + m_directions &= ~TouchMoveDirectionRight; + + if (deltaYmovement > 0.0f) + m_directions &= ~TouchMoveDirectionUp; + else if (deltaYmovement < 0.0f) + m_directions &= ~TouchMoveDirectionDown; + + if (m_directions == TouchMoveDirectionNone) + { + m_done = true; + return false; + } + + float deltaXabs = abs(pointer.current.x - pointer.down.x); + float deltaYabs = abs(pointer.current.y - pointer.down.y); + float varXabs = deltaYabs * SWIPE_MAX_VARIANCE_ANGLE + (m_dpi * SWIPE_MAX_VARIANCE) / 2; + float varYabs = deltaXabs * SWIPE_MAX_VARIANCE_ANGLE + (m_dpi * SWIPE_MAX_VARIANCE) / 2; + + if (m_directions & TouchMoveDirectionLeft) + { + // check if the movement went too much in Y direction + if (deltaYabs > varYabs) + m_directions &= ~TouchMoveDirectionLeft; + // check if the movement went far enough in the X direction + else if (deltaXabs > m_dpi * SWIPE_MIN_DISTANCE) + m_swipeDetected = true; + } + + if (m_directions & TouchMoveDirectionRight) + { + // check if the movement went too much in Y direction + if (deltaYabs > varYabs) + m_directions &= ~TouchMoveDirectionRight; + // check if the movement went far enough in the X direction + else if (deltaXabs > m_dpi * SWIPE_MIN_DISTANCE) + m_swipeDetected = true; + } + + if (m_directions & TouchMoveDirectionUp) + { + // check if the movement went too much in X direction + if (deltaXabs > varXabs) + m_directions &= ~TouchMoveDirectionUp; + // check if the movement went far enough in the Y direction + else if (deltaYabs > m_dpi * SWIPE_MIN_DISTANCE) + m_swipeDetected = true; + } + + if (m_directions & TouchMoveDirectionDown) + { + // check if the movement went too much in X direction + if (deltaXabs > varXabs) + m_directions &= ~TouchMoveDirectionDown; + // check if the movement went far enough in the Y direction + else if (deltaYabs > m_dpi * SWIPE_MIN_DISTANCE) + m_swipeDetected = true; + } + + if (m_directions == TouchMoveDirectionNone) + { + m_done = true; + return false; + } + + return true; +} + +bool CGenericTouchSwipeDetector::OnTouchUpdate(unsigned int index, const Pointer &pointer) +{ + if (index < 0 || index >= TOUCH_MAX_POINTERS) + return false; + + if (m_done) + return true; + + return OnTouchMove(index, pointer); +} diff --git a/src/input/touch/generic/GenericTouchSwipeDetector.h b/src/input/touch/generic/GenericTouchSwipeDetector.h new file mode 100644 index 0000000000..528b6d6a07 --- /dev/null +++ b/src/input/touch/generic/GenericTouchSwipeDetector.h @@ -0,0 +1,60 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "input/touch/generic/IGenericTouchGestureDetector.h" + +/*! + * \ingroup touch_generic + * \brief Implementation of IGenericTouchGestureDetector to detect swipe + * gestures in any direction. + * + * \sa IGenericTouchGestureDetector + */ +class CGenericTouchSwipeDetector : public IGenericTouchGestureDetector +{ +public: + CGenericTouchSwipeDetector(ITouchActionHandler *handler, float dpi); + virtual ~CGenericTouchSwipeDetector() { } + + virtual bool OnTouchDown(unsigned int index, const Pointer &pointer); + virtual bool OnTouchUp(unsigned int index, const Pointer &pointer); + virtual bool OnTouchMove(unsigned int index, const Pointer &pointer); + virtual bool OnTouchUpdate(unsigned int index, const Pointer &pointer); + +private: + /*! + * \brief Swipe directions that are still possible to detect + * + * The directions are stored as a combination (bitwise OR) of + * TouchMoveDirection enum values + * + * \sa TouchMoveDirection + */ + unsigned int m_directions; + /*! + * \brief Whether a swipe gesture has been detected or not + */ + bool m_swipeDetected; + /*! + * \brief Number of active pointeres + */ + unsigned int m_size; +}; diff --git a/src/input/touch/generic/IGenericTouchGestureDetector.h b/src/input/touch/generic/IGenericTouchGestureDetector.h new file mode 100644 index 0000000000..c52dbc0403 --- /dev/null +++ b/src/input/touch/generic/IGenericTouchGestureDetector.h @@ -0,0 +1,103 @@ +#pragma once +/* + * Copyright (C) 2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "input/touch/ITouchInputHandling.h" +#include "input/touch/TouchTypes.h" + +#define TOUCH_MAX_POINTERS 2 + +/*! + * \ingroup touch_generic + * \brief Interface defining methods to perform gesture recognition + */ +class IGenericTouchGestureDetector : public ITouchInputHandling +{ +public: + IGenericTouchGestureDetector(ITouchActionHandler *handler, float dpi) + : m_done(false), + m_dpi(dpi) + { + RegisterHandler(handler); + } + virtual ~IGenericTouchGestureDetector() { } + + /*! + * \brief Check whether the gesture recognition is finished or not + * + * \return True if the gesture recognition is finished otherwise false + */ + bool IsDone() { return m_done; } + + /*! + * \brief A new touch pointer has been recognised. + * + * \param index Index of the given touch pointer + * \param pointer Touch pointer that has changed + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchDown(unsigned int index, const Pointer &pointer) = 0; + /*! + * \brief An active touch pointer has vanished. + * + * If the first touch pointer is lifted and there are more active touch + * pointers, the remaining pointers change their index. + * + * \param index Index of the given touch pointer + * \param pointer Touch pointer that has changed + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchUp(unsigned int index, const Pointer &pointer) { return false; } + /*! + * \brief An active touch pointer has moved. + * + * \param index Index of the given touch pointer + * \param pointer Touch pointer that has changed + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchMove(unsigned int index, const Pointer &pointer) { return false; } + /*! + * \brief An active touch pointer's values have been updated but no event has + * occured. + * + * \param index Index of the given touch pointer + * \param pointer Touch pointer that has changed + * + * \return True if the event was handled otherwise false + */ + virtual bool OnTouchUpdate(unsigned int index, const Pointer &pointer) { return false; } + +protected: + /*! + * \brief Whether the gesture recognition is finished or not + */ + bool m_done; + /*! + * \brief DPI value of the touch screen + */ + float m_dpi; + /*! + * \brief Local list of all known touch pointers + */ + Pointer m_pointers[TOUCH_MAX_POINTERS]; +}; diff --git a/src/input/touch/generic/Makefile b/src/input/touch/generic/Makefile new file mode 100644 index 0000000000..5c3d89fc11 --- /dev/null +++ b/src/input/touch/generic/Makefile @@ -0,0 +1,10 @@ +SRCS=GenericTouchActionHandler.cpp \ + GenericTouchInputHandler.cpp \ + GenericTouchPinchDetector.cpp \ + GenericTouchRotateDetector.cpp \ + GenericTouchSwipeDetector.cpp \ + +LIB=input_touch_generic.a + +include ../../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) |