Permalink
Browse files

Merge pull request #2135 from Montellese/touch_input

generic & user-mappable touch input system
  • Loading branch information...
2 parents ad6733b + 967c20b commit e46bb02b700dee743d384e5166a57367571018ab @Montellese Montellese committed Mar 7, 2013
Showing with 2,622 additions and 1,314 deletions.
  1. +2 −0 Makefile.in
  2. +40 −0 XBMC-IOS.xcodeproj/project.pbxproj
  3. +21 −0 system/keymaps/touchscreen.xml
  4. +13 −0 xbmc/Application.cpp
  5. +14 −109 xbmc/android/activity/AndroidTouch.cpp
  6. +1 −20 xbmc/android/activity/AndroidTouch.h
  7. +10 −8 xbmc/guilib/GUIControl.h
  8. +31 −11 xbmc/guilib/Key.h
  9. +170 −0 xbmc/input/ButtonTranslator.cpp
  10. +9 −0 xbmc/input/ButtonTranslator.h
  11. +0 −1 xbmc/input/Makefile
  12. +0 −600 xbmc/input/TouchInput.cpp
  13. +0 −428 xbmc/input/TouchInput.h
  14. +240 −0 xbmc/input/touch/ITouchActionHandler.h
  15. +104 −0 xbmc/input/touch/ITouchInputHandler.h
  16. +155 −0 xbmc/input/touch/ITouchInputHandling.cpp
  17. +87 −0 xbmc/input/touch/ITouchInputHandling.h
  18. +6 −0 xbmc/input/touch/Makefile
  19. +120 −0 xbmc/input/touch/TouchTypes.h
  20. +193 −0 xbmc/input/touch/generic/GenericTouchActionHandler.cpp
  21. +83 −0 xbmc/input/touch/generic/GenericTouchActionHandler.h
  22. +394 −0 xbmc/input/touch/generic/GenericTouchInputHandler.cpp
  23. +96 −0 xbmc/input/touch/generic/GenericTouchInputHandler.h
  24. +99 −0 xbmc/input/touch/generic/GenericTouchPinchDetector.cpp
  25. +42 −0 xbmc/input/touch/generic/GenericTouchPinchDetector.h
  26. +129 −0 xbmc/input/touch/generic/GenericTouchRotateDetector.cpp
  27. +47 −0 xbmc/input/touch/generic/GenericTouchRotateDetector.h
  28. +157 −0 xbmc/input/touch/generic/GenericTouchSwipeDetector.cpp
  29. +55 −0 xbmc/input/touch/generic/GenericTouchSwipeDetector.h
  30. +103 −0 xbmc/input/touch/generic/IGenericTouchGestureDetector.h
  31. +10 −0 xbmc/input/touch/generic/Makefile
  32. +0 −3 xbmc/osx/ios/XBMCController.h
  33. +143 −104 xbmc/osx/ios/XBMCController.mm
  34. +26 −17 xbmc/pictures/GUIWindowSlideShow.cpp
  35. +4 −0 xbmc/pictures/SlideShowPicture.cpp
  36. +1 −0 xbmc/pictures/SlideShowPicture.h
  37. +11 −0 xbmc/windowing/XBMC_events.h
  38. +0 −7 xbmc/windowing/android/WinEventsAndroid.cpp
  39. +6 −6 xbmc/windowing/windows/WinEventsWin32.cpp
View
2 Makefile.in
@@ -126,6 +126,8 @@ DIRECTORY_ARCHIVES += xbmc/windowing/osx/windowing_osx.a
else
ifeq (@USE_ANDROID@,1)
DIRECTORY_ARCHIVES += xbmc/input/linux/input_linux.a
+DIRECTORY_ARCHIVES += xbmc/input/touch/input_touch.a
+DIRECTORY_ARCHIVES += xbmc/input/touch/generic/input_touch_generic.a
DIRECTORY_ARCHIVES += xbmc/network/linux/network_linux.a
DIRECTORY_ARCHIVES += xbmc/powermanagement/android/powermanagement_android.a
DIRECTORY_ARCHIVES += xbmc/storage/android/storage_android.a
View
40 XBMC-IOS.xcodeproj/project.pbxproj
@@ -17,6 +17,9 @@
18B700F613A6A7850009C1AF /* AddonVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B700F413A6A7850009C1AF /* AddonVersion.cpp */; };
18E7CAD71578C691001D4554 /* CDDARipJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18E7CAD51578C691001D4554 /* CDDARipJob.cpp */; };
18ECC99D13CF17D200A9ED6C /* StreamUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18ECC99B13CF17D200A9ED6C /* StreamUtils.cpp */; };
+ 1D04C1DA16E67B5A0001BA1E /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D04C1D816E67B5A0001BA1E /* Vector.cpp */; };
+ 1D04C23B16E67BA20001BA1E /* GenericTouchActionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D04C22916E67BA20001BA1E /* GenericTouchActionHandler.cpp */; };
+ 1D04C24116E67BA20001BA1E /* ITouchInputHandling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D04C23716E67BA20001BA1E /* ITouchInputHandling.cpp */; };
1D638120161E20F2003603ED /* PeripheralImon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D63811E161E20F2003603ED /* PeripheralImon.cpp */; };
3255316612B2D02400837CD2 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3255316512B2D02400837CD2 /* CoreAudio.framework */; };
3291892B1423A9B700E878CD /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 329189291423A9B700E878CD /* JpegIO.cpp */; };
@@ -1055,6 +1058,15 @@
18E7CAD61578C691001D4554 /* CDDARipJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDDARipJob.h; sourceTree = "<group>"; };
18ECC99B13CF17D200A9ED6C /* StreamUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamUtils.cpp; sourceTree = "<group>"; };
18ECC99C13CF17D200A9ED6C /* StreamUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamUtils.h; sourceTree = "<group>"; };
+ 1D04C1D816E67B5A0001BA1E /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = "<group>"; };
+ 1D04C1D916E67B5A0001BA1E /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; };
+ 1D04C22916E67BA20001BA1E /* GenericTouchActionHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericTouchActionHandler.cpp; sourceTree = "<group>"; };
+ 1D04C22A16E67BA20001BA1E /* GenericTouchActionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericTouchActionHandler.h; sourceTree = "<group>"; };
+ 1D04C23516E67BA20001BA1E /* ITouchActionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITouchActionHandler.h; sourceTree = "<group>"; };
+ 1D04C23616E67BA20001BA1E /* ITouchInputHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITouchInputHandler.h; sourceTree = "<group>"; };
+ 1D04C23716E67BA20001BA1E /* ITouchInputHandling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ITouchInputHandling.cpp; sourceTree = "<group>"; };
+ 1D04C23816E67BA20001BA1E /* ITouchInputHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITouchInputHandling.h; sourceTree = "<group>"; };
+ 1D04C23A16E67BA20001BA1E /* TouchTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchTypes.h; sourceTree = "<group>"; };
1D63811E161E20F2003603ED /* PeripheralImon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralImon.cpp; sourceTree = "<group>"; };
1D63811F161E20F2003603ED /* PeripheralImon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralImon.h; sourceTree = "<group>"; };
3255316512B2D02400837CD2 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
@@ -3300,6 +3312,28 @@
name = Products;
sourceTree = "<group>";
};
+ 1D04C22716E67BA20001BA1E /* touch */ = {
+ isa = PBXGroup;
+ children = (
+ 1D04C22816E67BA20001BA1E /* generic */,
+ 1D04C23516E67BA20001BA1E /* ITouchActionHandler.h */,
+ 1D04C23616E67BA20001BA1E /* ITouchInputHandler.h */,
+ 1D04C23716E67BA20001BA1E /* ITouchInputHandling.cpp */,
+ 1D04C23816E67BA20001BA1E /* ITouchInputHandling.h */,
+ 1D04C23A16E67BA20001BA1E /* TouchTypes.h */,
+ );
+ path = touch;
+ sourceTree = "<group>";
+ };
+ 1D04C22816E67BA20001BA1E /* generic */ = {
+ isa = PBXGroup;
+ children = (
+ 1D04C22916E67BA20001BA1E /* GenericTouchActionHandler.cpp */,
+ 1D04C22A16E67BA20001BA1E /* GenericTouchActionHandler.h */,
+ );
+ path = generic;
+ sourceTree = "<group>";
+ };
83D619BA13C0D23400418A0F /* Documentation */ = {
isa = PBXGroup;
children = (
@@ -5615,6 +5649,7 @@
F56C8536131F42E9000AD0F6 /* input */ = {
isa = PBXGroup;
children = (
+ 1D04C22716E67BA20001BA1E /* touch */,
F56C8537131F42E9000AD0F6 /* ButtonTranslator.cpp */,
F56C8538131F42E9000AD0F6 /* ButtonTranslator.h */,
DFAB04AE13F8383300B70BFB /* InertialScrollingHandler.cpp */,
@@ -6226,6 +6261,8 @@
36A9467715CF20A500727135 /* UrlOptions.h */,
F56C875D131F42EC000AD0F6 /* Variant.cpp */,
F56C875E131F42EC000AD0F6 /* Variant.h */,
+ 1D04C1D816E67B5A0001BA1E /* Vector.cpp */,
+ 1D04C1D916E67B5A0001BA1E /* Vector.h */,
F56C875F131F42EC000AD0F6 /* Weather.cpp */,
F56C8760131F42EC000AD0F6 /* Weather.h */,
F56C8763131F42EC000AD0F6 /* WindowsShortcut.h */,
@@ -7695,6 +7732,9 @@
F56352F916E5440300D21BAD /* GUIDialogProfileSettings.cpp in Sources */,
F56352FA16E5440300D21BAD /* GUIDialogSettings.cpp in Sources */,
F56352FD16E5441600D21BAD /* AppParamParser.cpp in Sources */,
+ 1D04C1DA16E67B5A0001BA1E /* Vector.cpp in Sources */,
+ 1D04C23B16E67BA20001BA1E /* GenericTouchActionHandler.cpp in Sources */,
+ 1D04C24116E67BA20001BA1E /* ITouchInputHandling.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
21 system/keymaps/touchscreen.xml
@@ -0,0 +1,21 @@
+<keymap>
+ <global>
+ <touch>
+ <tap>LeftClick</tap>
+ <longpress>RightClick</longpress>
+ <tap pointers="2">RightClick</tap>
+ <pan>PanGesture</pan>
+ <swipe direction="left">SwipeLeft</swipe>
+ <swipe direction="left" pointers="2">Back</swipe>
+ <swipe direction="right">SwipeRight</swipe>
+ <swipe direction="up">SwipeUp</swipe>
+ <swipe direction="down">SwipeDown</swipe>
+ </touch>
+ </global>
+ <SlideShow>
+ <touch>
+ <zoom>ZoomGesture</zoom>
+ <rotate>RotateGesture</rotate>
+ </touch>
+ </SlideShow>
+</keymap>
View
13 xbmc/Application.cpp
@@ -519,6 +519,19 @@ bool CApplication::OnEvent(XBMC_Event& newEvent)
break;
case XBMC_APPCOMMAND:
return g_application.OnAppCommand(newEvent.appcommand.action);
+ case XBMC_TOUCH:
+ {
+ int windowId = g_windowManager.GetActiveWindow() & WINDOW_ID_MASK;
+ int actionId = 0;
+ if (newEvent.touch.action == ACTION_GESTURE_BEGIN || newEvent.touch.action == ACTION_GESTURE_END)
+ actionId = newEvent.touch.action;
+ else if (!CButtonTranslator::GetInstance().TranslateTouchAction(windowId, newEvent.touch.action, newEvent.touch.pointers, actionId) ||
+ actionId <= 0)
+ return false;
+
+ CApplicationMessenger::Get().SendAction(CAction(actionId, 0, newEvent.touch.x, newEvent.touch.y, newEvent.touch.x2, newEvent.touch.y2), WINDOW_INVALID, false);
+ break;
+ }
}
return true;
}
View
123 xbmc/android/activity/AndroidTouch.cpp
@@ -19,24 +19,22 @@
*/
#include "AndroidTouch.h"
-#include "XBMCApp.h"
-#include "guilib/GUIWindowManager.h"
-#include "windowing/WinEvents.h"
-#include "ApplicationMessenger.h"
+#include "android/activity/XBMCApp.h"
+#include "input/touch/generic/GenericTouchActionHandler.h"
+#include "input/touch/generic/GenericTouchInputHandler.h"
CAndroidTouch::CAndroidTouch() : m_dpi(160)
{
- CTouchInput::Get().RegisterHandler(this);
+ CGenericTouchInputHandler::Get().RegisterHandler(&CGenericTouchActionHandler::Get());
}
CAndroidTouch::~CAndroidTouch()
{
- CTouchInput::Get().UnregisterHandler();
+ CGenericTouchInputHandler::Get().UnregisterHandler();
}
bool CAndroidTouch::onTouchEvent(AInputEvent* event)
{
- CXBMCApp::android_printf("%s", __PRETTY_FUNCTION__);
if (event == NULL)
return false;
@@ -54,21 +52,21 @@ bool CAndroidTouch::onTouchEvent(AInputEvent* event)
int8_t touchAction = eventAction & AMOTION_EVENT_ACTION_MASK;
size_t touchPointer = eventAction >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- CTouchInput::TouchEvent touchEvent = CTouchInput::TouchEventAbort;
+ TouchInput touchEvent = TouchInputAbort;
switch (touchAction)
{
case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_POINTER_DOWN:
- touchEvent = CTouchInput::TouchEventDown;
+ touchEvent = TouchInputDown;
break;
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_POINTER_UP:
- touchEvent = CTouchInput::TouchEventUp;
+ touchEvent = TouchInputUp;
break;
case AMOTION_EVENT_ACTION_MOVE:
- touchEvent = CTouchInput::TouchEventMove;
+ touchEvent = TouchInputMove;
break;
case AMOTION_EVENT_ACTION_OUTSIDE:
@@ -84,112 +82,19 @@ bool CAndroidTouch::onTouchEvent(AInputEvent* event)
// first update all touch pointers
for (unsigned int pointer = 0; pointer < numPointers; pointer++)
- CTouchInput::Get().Update(pointer, AMotionEvent_getX(event, pointer), AMotionEvent_getY(event, pointer),
+ CGenericTouchInputHandler::Get().UpdateTouchPointer(pointer, AMotionEvent_getX(event, pointer), AMotionEvent_getY(event, pointer),
AMotionEvent_getEventTime(event), m_dpi / 16.0f);
// now send the event
- return CTouchInput::Get().Handle(touchEvent, x, y, time, touchPointer, size);
-}
-
-bool CAndroidTouch::OnSingleTouchStart(float x, float y)
-{
- // Send a mouse motion event for getting the current guiitem selected
- XBMC_Touch(XBMC_MOUSEMOTION, 0, (uint16_t)x, (uint16_t)y);
-
- return true;
-}
-
-bool CAndroidTouch::OnMultiTouchStart(float x, float y, int32_t pointers /* = 2 */)
-{
- XBMC_TouchGesture(ACTION_GESTURE_BEGIN, x, y, 0.0f, 0.0f);
-
- return true;
-}
-
-bool CAndroidTouch::OnMultiTouchEnd(float x, float y, int32_t pointers /* = 2 */)
-{
- XBMC_TouchGesture(ACTION_GESTURE_END, 0.0f, 0.0f, 0.0f, 0.0f);
-
- return true;
-}
-
-bool CAndroidTouch::OnTouchGesturePanStart(float x, float y)
-{
- XBMC_TouchGesture(ACTION_GESTURE_BEGIN, x, y, 0.0f, 0.0f);
-
- return true;
-}
-
-bool CAndroidTouch::OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
-{
- XBMC_TouchGesture(ACTION_GESTURE_PAN, x, y, offsetX, offsetY);
-
- return true;
-}
-
-bool CAndroidTouch::OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
-{
- XBMC_TouchGesture(ACTION_GESTURE_END, velocityX, velocityY, x, y);
-
- // unfocus the focused GUI item
- g_windowManager.SendMessage(GUI_MSG_UNFOCUS_ALL, 0, 0, 0, 0);
-
- return true;
-}
-
-void CAndroidTouch::OnSingleTap(float x, float y)
-{
- XBMC_Touch(XBMC_MOUSEBUTTONDOWN, XBMC_BUTTON_LEFT, (uint16_t)x, (uint16_t)y);
- XBMC_Touch(XBMC_MOUSEBUTTONUP, XBMC_BUTTON_LEFT, (uint16_t)x, (uint16_t)y);
-}
-
-void CAndroidTouch::OnSingleLongPress(float x, float y)
-{
- // we send a right-click for this
- XBMC_Touch(XBMC_MOUSEBUTTONDOWN, XBMC_BUTTON_RIGHT, (uint16_t)x, (uint16_t)y);
- XBMC_Touch(XBMC_MOUSEBUTTONUP, XBMC_BUTTON_RIGHT, (uint16_t)x, (uint16_t)y);
-}
-
-void CAndroidTouch::OnZoomPinch(float centerX, float centerY, float zoomFactor)
-{
- XBMC_TouchGesture(ACTION_GESTURE_ZOOM, centerX, centerY, zoomFactor, 0);
-}
-
-void CAndroidTouch::OnRotate(float centerX, float centerY, float angle)
-{
- XBMC_TouchGesture(ACTION_GESTURE_ROTATE, centerX, centerY, angle, 0);
+ return CGenericTouchInputHandler::Get().HandleTouchInput(touchEvent, x, y, time, touchPointer, size);
}
void CAndroidTouch::setDPI(uint32_t dpi)
{
if (dpi != 0)
+ {
m_dpi = dpi;
-}
-void CAndroidTouch::XBMC_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;
-
- CXBMCApp::android_printf("XBMC_Touch(%u, %u, %u, %u)", type, button, x, y);
- CWinEvents::MessagePush(&newEvent);
-}
-
-void CAndroidTouch::XBMC_TouchGesture(int32_t action, float posX, float posY, float offsetX, float offsetY)
-{
- CXBMCApp::android_printf("XBMC_TouchGesture(%d, %f, %f, %f, %f)", action, posX, posY, offsetX, offsetY);
- if (action == ACTION_GESTURE_BEGIN)
- CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, 0, 0), WINDOW_INVALID, false);
- else if (action == ACTION_GESTURE_PAN)
- CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, offsetY), WINDOW_INVALID, false);
- else if (action == ACTION_GESTURE_END)
- CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, offsetY), WINDOW_INVALID, false);
- else if (action == ACTION_GESTURE_ZOOM || action == ACTION_GESTURE_ROTATE)
- CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, 0), WINDOW_INVALID, false);
+ CGenericTouchInputHandler::Get().SetScreenDPI(m_dpi);
+ }
}
View
21 xbmc/android/activity/AndroidTouch.h
@@ -21,9 +21,7 @@
#include <android/input.h>
#include <math.h>
-#include "input/TouchInput.h"
-
-class CAndroidTouch : protected ITouchHandler
+class CAndroidTouch
{
public:
@@ -32,25 +30,8 @@ class CAndroidTouch : protected ITouchHandler
bool onTouchEvent(AInputEvent* event);
protected:
- virtual bool OnSingleTouchStart(float x, float y);
-
- virtual bool OnMultiTouchStart(float x, float y, int32_t pointers = 2);
- virtual bool OnMultiTouchEnd(float x, float y, int32_t pointers = 2);
-
- virtual bool OnTouchGesturePanStart(float x, float y);
- virtual bool OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY);
- virtual bool OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY);
-
- virtual void OnSingleTap(float x, float y);
- virtual void OnSingleLongPress(float x, float y);
- virtual void OnZoomPinch(float centerX, float centerY, float zoomFactor);
- virtual void OnRotate(float centerX, float centerY, float angle);
-
virtual void setDPI(uint32_t dpi);
private:
- void XBMC_Touch(uint8_t type, uint8_t button, uint16_t x, uint16_t y);
- void XBMC_TouchGesture(int32_t action, float posX, float posY, float offsetX, float offsetY);
-
uint32_t m_dpi;
};
View
18 xbmc/guilib/GUIControl.h
@@ -56,14 +56,16 @@ class CControlState
\brief Results of OnMouseEvent()
Any value not equal to EVENT_RESULT_UNHANDLED indicates that the event was handled.
*/
-enum EVENT_RESULT { EVENT_RESULT_UNHANDLED = 0,
- EVENT_RESULT_HANDLED,
- EVENT_RESULT_PAN_HORIZONTAL,
- EVENT_RESULT_PAN_VERTICAL,
- EVENT_RESULT_PAN_VERTICAL_WITHOUT_INERTIA,
- EVENT_RESULT_PAN_HORIZONTAL_WITHOUT_INERTIA,
- EVENT_RESULT_ROTATE,
- EVENT_RESULT_ZOOM };
+enum EVENT_RESULT { EVENT_RESULT_UNHANDLED = 0x00,
+ EVENT_RESULT_HANDLED = 0x01,
+ EVENT_RESULT_PAN_HORIZONTAL = 0x02,
+ EVENT_RESULT_PAN_VERTICAL = 0x04,
+ EVENT_RESULT_PAN_VERTICAL_WITHOUT_INERTIA = 0x08,
+ EVENT_RESULT_PAN_HORIZONTAL_WITHOUT_INERTIA = 0x10,
+ EVENT_RESULT_ROTATE = 0x20,
+ EVENT_RESULT_ZOOM = 0x40,
+ EVENT_RESULT_SWIPE = 0x80
+};
/*!
\ingroup controls
View
42 xbmc/guilib/Key.h
@@ -81,6 +81,9 @@
// 0xD000 -> 0xD0FF is reserved for WM_APPCOMMAND messages
#define KEY_APPCOMMAND 0xD000
+// 0xF000 -> 0xF0FF is reserved for mouse actions
+#define KEY_TOUCH 0xF000
+
#define KEY_INVALID 0xFFFF
// actions that we have defined...
@@ -293,22 +296,11 @@
#define ACTION_INCREASE_PAR 219
#define ACTION_DECREASE_PAR 220
-#define ACTION_GESTURE_NOTIFY 221
-#define ACTION_GESTURE_BEGIN 222
-#define ACTION_GESTURE_ZOOM 223 //sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0)
-#define ACTION_GESTURE_ROTATE 224
-#define ACTION_GESTURE_PAN 225
-#define ACTION_GESTURE_END 226
#define ACTION_VSHIFT_UP 227 // shift up video image in DVDPlayer
#define ACTION_VSHIFT_DOWN 228 // shift down video image in DVDPlayer
#define ACTION_PLAYER_PLAYPAUSE 229 // Play/pause. If playing it pauses, if paused it plays.
-// The NOOP action can be specified to disable an input event. This is
-// useful in user keyboard.xml etc to disable actions specified in the
-// system mappings.
-#define ACTION_NOOP 999
-
#define ACTION_SUBTITLE_VSHIFT_UP 230 // shift up subtitles in DVDPlayer
#define ACTION_SUBTITLE_VSHIFT_DOWN 231 // shift down subtitles in DVDPlayer
#define ACTION_SUBTITLE_ALIGN 232 // toggle vertical alignment of subtitles
@@ -317,6 +309,34 @@
#define ACTION_SWITCH_PLAYER 234
+// touch actions
+#define ACTION_TOUCH_TAP 401
+#define ACTION_TOUCH_TAP_TEN 410
+#define ACTION_TOUCH_LONGPRESS 411
+#define ACTION_TOUCH_LONGPRESS_TEN 420
+
+#define ACTION_GESTURE_NOTIFY 500
+#define ACTION_GESTURE_BEGIN 501
+#define ACTION_GESTURE_ZOOM 502 //sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0)
+#define ACTION_GESTURE_ROTATE 503
+#define ACTION_GESTURE_PAN 504
+
+#define ACTION_GESTURE_SWIPE_LEFT 511
+#define ACTION_GESTURE_SWIPE_LEFT_TEN 520
+#define ACTION_GESTURE_SWIPE_RIGHT 521
+#define ACTION_GESTURE_SWIPE_RIGHT_TEN 530
+#define ACTION_GESTURE_SWIPE_UP 531
+#define ACTION_GESTURE_SWIPE_UP_TEN 540
+#define ACTION_GESTURE_SWIPE_DOWN 541
+#define ACTION_GESTURE_SWIPE_DOWN_TEN 550
+// 5xx is reserved for additional gesture actions
+#define ACTION_GESTURE_END 599
+
+// The NOOP action can be specified to disable an input event. This is
+// useful in user keyboard.xml etc to disable actions specified in the
+// system mappings.
+#define ACTION_NOOP 999
+
// Window ID defines to make the code a bit more readable
#define WINDOW_INVALID 9999
#define WINDOW_HOME 10000
View
170 xbmc/input/ButtonTranslator.cpp
@@ -234,6 +234,17 @@ static const ActionMapping actions[] =
{"mousedrag" , ACTION_MOUSE_DRAG},
{"mousemove" , ACTION_MOUSE_MOVE},
+ // Touch
+ {"tap" , ACTION_TOUCH_TAP},
+ {"longpress" , ACTION_TOUCH_LONGPRESS},
+ {"pangesture" , ACTION_GESTURE_PAN},
+ {"zoomgesture" , ACTION_GESTURE_ZOOM},
+ {"rotategesture" , ACTION_GESTURE_ROTATE},
+ {"swipeleft" , ACTION_GESTURE_SWIPE_LEFT},
+ {"swiperight" , ACTION_GESTURE_SWIPE_RIGHT},
+ {"swipeup" , ACTION_GESTURE_SWIPE_UP},
+ {"swipedown" , ACTION_GESTURE_SWIPE_DOWN},
+
// Do nothing action
{ "noop" , ACTION_NOOP}
};
@@ -367,6 +378,19 @@ static const ActionMapping mousecommands[] =
{ "mousemove", ACTION_MOUSE_MOVE }
};
+static const ActionMapping touchcommands[] =
+{
+ { "tap", ACTION_TOUCH_TAP },
+ { "longpress", ACTION_TOUCH_LONGPRESS },
+ { "pan", ACTION_GESTURE_PAN },
+ { "zoom", ACTION_GESTURE_ZOOM },
+ { "rotate", ACTION_GESTURE_ROTATE },
+ { "swipeleft", ACTION_GESTURE_SWIPE_LEFT },
+ { "swiperight", ACTION_GESTURE_SWIPE_RIGHT },
+ { "swipeup", ACTION_GESTURE_SWIPE_UP },
+ { "swipedown", ACTION_GESTURE_SWIPE_DOWN }
+};
+
static const WindowMapping fallbackWindows[] =
{
{ WINDOW_FULLSCREEN_LIVETV, WINDOW_FULLSCREEN_VIDEO },
@@ -842,6 +866,35 @@ bool CButtonTranslator::TranslateJoystickString(int window, const char* szDevice
return (action > 0);
}
+bool CButtonTranslator::TranslateTouchAction(int window, int touchAction, int touchPointers, int &action)
+{
+ action = 0;
+ if (touchPointers <= 0)
+ touchPointers = 1;
+
+ touchAction += touchPointers - 1;
+ touchAction |= KEY_TOUCH;
+
+ action = GetTouchActionCode(window, touchAction);
+ if (action <= 0)
+ action = GetTouchActionCode(-1, touchAction);
+
+ return action > 0;
+}
+
+int CButtonTranslator::GetActionCode(int window, int action)
+{
+ map<int, buttonMap>::const_iterator it = m_translatorMap.find(window);
+ if (it == m_translatorMap.end())
+ return 0;
+
+ buttonMap::const_iterator it2 = it->second.find(action);
+ if (it2 == it->second.end())
+ return 0;
+
+ return it2->second.id;
+}
+
/*
* Translates a joystick input to an action code
*/
@@ -975,6 +1028,7 @@ void CButtonTranslator::MapAction(uint32_t buttonCode, const char *szAction, but
int action = ACTION_NONE;
if (!TranslateActionString(szAction, action) || !buttonCode)
return; // no valid action, or an invalid buttoncode
+
// have a valid action, and a valid button - map it.
// check to see if we've already got this (button,action) pair defined
buttonMap::iterator it = map.find(buttonCode);
@@ -1059,6 +1113,16 @@ void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID)
}
}
#endif
+
+ if ((pDevice = pWindow->FirstChild("touch")) != NULL)
+ {
+ // map touch actions
+ while (pDevice)
+ {
+ MapTouchActions(windowID, pDevice);
+ pDevice = pDevice->NextSibling("touch");
+ }
+ }
}
bool CButtonTranslator::TranslateActionString(const char *szAction, int &action)
@@ -1379,3 +1443,109 @@ void CButtonTranslator::Clear()
m_Loaded = false;
}
+
+uint32_t CButtonTranslator::TranslateTouchCommand(TiXmlElement *pButton, CButtonAction &action)
+{
+ const char *szButton = pButton->Value();
+ if (szButton == NULL || pButton->FirstChild() == NULL)
+ return ACTION_NONE;
+
+ const char *szAction = pButton->FirstChild()->Value();
+ if (szAction == NULL)
+ return ACTION_NONE;
+
+ CStdString strTouchCommand = szButton;
+ strTouchCommand.ToLower();
+
+ std::string strTmp;
+ if (pButton->QueryStringAttribute("direction", &strTmp) == TIXML_SUCCESS)
+ strTouchCommand += strTmp;
+
+ uint32_t actionId = ACTION_NONE;
+ for (unsigned int i = 0; i < sizeof(touchcommands)/sizeof(touchcommands[0]); i++)
+ {
+ if (strTouchCommand.Equals(touchcommands[i].name))
+ {
+ actionId = touchcommands[i].action;
+ break;
+ }
+ }
+
+ if (actionId <= ACTION_NONE)
+ {
+ CLog::Log(LOGERROR, "%s: Can't find touch command %s", __FUNCTION__, szButton);
+ return ACTION_NONE;
+ }
+
+ strTmp.clear();
+ if (pButton->QueryStringAttribute("pointers", &strTmp) == TIXML_SUCCESS)
+ {
+ int pointers = (int)strtol(strTmp.c_str(), NULL, 0);
+ if (pointers >= 1)
+ actionId += pointers - 1;
+ }
+
+ action.strID = szAction;
+ if (!TranslateActionString(szAction, action.id) || action.id <= ACTION_NONE)
+ return ACTION_NONE;
+
+ return actionId | KEY_TOUCH;
+}
+
+void CButtonTranslator::MapTouchActions(int windowID, TiXmlNode *pTouch)
+{
+ if (pTouch == NULL)
+ return;
+
+ buttonMap map;
+ // check if there already is a touch map for the window ID
+ std::map<int, buttonMap>::iterator it = m_touchMap.find(windowID);
+ if (it != m_touchMap.end())
+ {
+ // get the existing touch map and remove it from the window mapping
+ // as it will be inserted later on
+ map = it->second;
+ m_touchMap.erase(it);
+ }
+
+ uint32_t actionId = 0;
+ TiXmlElement *pTouchElem = pTouch->ToElement();
+ if (pTouchElem == NULL)
+ return;
+
+ TiXmlElement *pButton = pTouchElem->FirstChildElement();
+ while (pButton != NULL)
+ {
+ CButtonAction action;
+ actionId = TranslateTouchCommand(pButton, action);
+ if (actionId > 0)
+ {
+ // check if there already is a mapping for the parsed action
+ // and remove it if necessary
+ buttonMap::iterator actionIt = map.find(actionId);
+ if (actionIt != map.end())
+ map.erase(actionIt);
+
+ map.insert(std::make_pair(actionId, action));
+ }
+
+ pButton = pButton->NextSiblingElement();
+ }
+
+ // add the modified touch map with the window ID
+ if (map.size() > 0)
+ m_touchMap.insert(std::pair<int, buttonMap>(windowID, map));
+}
+
+int CButtonTranslator::GetTouchActionCode(int window, int action)
+{
+ std::map<int, buttonMap>::const_iterator windowIt = m_touchMap.find(window);
+ if (windowIt == m_touchMap.end())
+ return ACTION_NONE;
+
+ buttonMap::const_iterator touchIt = windowIt->second.find(action);
+ if (touchIt == windowIt->second.end())
+ return ACTION_NONE;
+
+ return touchIt->second.id;
+}
View
9 xbmc/input/ButtonTranslator.h
@@ -97,6 +97,8 @@ class CButtonTranslator
bool &fullrange);
#endif
+ bool TranslateTouchAction(int window, int touchAction, int touchPointers, int &action);
+
private:
typedef std::multimap<uint32_t, CButtonAction> buttonMap; // our button map to fill in
@@ -105,6 +107,7 @@ class CButtonTranslator
// m_deviceList contains the list of connected HID devices
std::list<CStdString> m_deviceList;
+ int GetActionCode(int window, int action);
int GetActionCode(int window, const CKey &key, CStdString &strAction) const;
#if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER)
typedef std::map<int, std::map<int, std::string> > JoystickMap; // <window, <button/axis, action> >
@@ -145,6 +148,12 @@ class CButtonTranslator
std::map<std::string, JoystickMap> m_joystickHatMap; // <joy name, hat map>
#endif
+ void MapTouchActions(int windowID, TiXmlNode *pTouch);
+ static uint32_t TranslateTouchCommand(TiXmlElement *pButton, CButtonAction &action);
+ int GetTouchActionCode(int window, int action);
+
+ std::map<int, buttonMap> m_touchMap;
+
bool m_Loaded;
};
View
1 xbmc/input/Makefile
@@ -4,7 +4,6 @@ SRCS=ButtonTranslator.cpp \
KeyboardStat.cpp \
MouseStat.cpp \
SDLJoystick.cpp \
- TouchInput.cpp \
XBMC_keytable.cpp \
LIB=input.a
View
600 xbmc/input/TouchInput.cpp
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Team XBMC
- * http://www.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 "TouchInput.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-
-#ifndef M_PI
-#define M_PI 3.1415926535897932384626433832795028842
-#endif
-
-CTouchInput::CTouchInput()
- : m_holdTimeout(1000),
- m_handler(NULL),
- m_fRotateAngle(0.0f),
- m_gestureState(TouchGestureUnknown),
- m_gestureStateOld(TouchGestureUnknown)
-{
- m_holdTimer = new CTimer(this);
-}
-
-CTouchInput::~CTouchInput()
-{
- delete m_holdTimer;
-}
-
-CTouchInput &CTouchInput::Get()
-{
- static CTouchInput sTouchInput;
- return sTouchInput;
-}
-
-void CTouchInput::RegisterHandler(ITouchHandler *touchHandler)
-{
- m_handler = touchHandler;
-}
-
-void CTouchInput::UnregisterHandler()
-{
- m_handler = NULL;
-}
-
-void CTouchInput::SetTouchHoldTimeout(int32_t timeout)
-{
- if (timeout <= 0)
- return;
-
- m_holdTimeout = timeout;
-}
-
-bool CTouchInput::Handle(TouchEvent 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 TouchEventAbort:
- {
- CLog::Log(LOGDEBUG, "CTouchInput: TouchEventAbort");
- setGestureState(TouchGestureUnknown);
- for (unsigned int pIndex = 0; pIndex < TOUCH_MAX_POINTERS; pIndex++)
- m_pointers[pIndex].reset();
-
- OnTouchAbort();
- break;
- }
-
- case TouchEventDown:
- {
- CLog::Log(LOGDEBUG, "CTouchInput: TouchEventDown");
- 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)
- {
- setGestureState(TouchGestureSingleTouch);
- result = OnSingleTouchStart(x, y);
-
- m_holdTimer->Start(m_holdTimeout);
- }
- // Otherwise it's the down event of another pointer
- else
- {
- // 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)
- {
- if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold)
- {
- result = OnMultiTouchStart(x, y);
-
- m_holdTimer->Stop(true);
- m_holdTimer->Start(m_holdTimeout);
- }
- else
- {
- result = OnMultiTouchDown(x, y, pointer);
-
- m_holdTimer->Stop(false);
- }
-
- setGestureState(TouchGestureMultiTouchStart);
- m_fRotateAngle = 0.0f;
- }
- // Otherwise we should ignore this pointer
- else
- {
- m_pointers[pointer].reset();
- break;
- }
- }
- return result;
- }
-
- case TouchEventUp:
- {
- CLog::Log(LOGDEBUG, "CTouchInput: TouchEventUp");
- // unexpected event => abort
- if (!m_pointers[pointer].valid() ||
- m_gestureState == TouchGestureUnknown)
- break;
-
- 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)
- OnSingleTap(x, y);
- }
- // 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 = OnTouchGesturePanEnd(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)
- {
- result = OnMultiTouchEnd(m_pointers[0].down.x, m_pointers[0].down.y);
-
- // if neither of the two pointers moved we have a double tap
- if (m_gestureStateOld != TouchGestureMultiTouchHold && m_gestureStateOld != TouchGestureMultiTouch)
- OnDoubleTap(m_pointers[0].down.x, m_pointers[0].down.y,
- m_pointers[1].down.x, m_pointers[1].down.y);
- }
-
- setGestureState(TouchGestureUnknown);
- }
-
- m_pointers[pointer].reset();
- return result;
- }
-
- case TouchEventMove:
- {
- CLog::Log(LOGDEBUG, "CTouchInput: TouchEventMove");
- // unexpected event => abort
- if (!m_pointers[pointer].valid() ||
- m_gestureState == TouchGestureUnknown ||
- m_gestureState == TouchGestureMultiTouchDone)
- break;
-
- if (m_pointers[pointer].moving)
- m_holdTimer->Stop();
-
- if (m_gestureState == TouchGestureSingleTouch)
- {
- // Check if the touch has moved far enough to count as movement
- if (!m_pointers[pointer].moving)
- break;
-
- result = OnTouchGesturePanStart(m_pointers[pointer].down.x, m_pointers[pointer].down.y);
-
- 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 (m_pointers[pointer].moving)
- result = OnMultiTouchMove(x, y,offsetX, offsetY, velocityX, velocityY, pointer);
-
- handleMultiTouchGesture();
- }
- else
- break;
-
- return result;
- }
-
- default:
- CLog::Log(LOGDEBUG, "CTouchInput: unknown TouchEvent");
- break;
- }
-
- return false;
-}
-
-bool CTouchInput::Update(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;
- }
-
- return true;
-}
-
-void CTouchInput::saveLastTouch()
-{
- for (unsigned int pointer = 0; pointer < TOUCH_MAX_POINTERS; pointer++)
- m_pointers[pointer].last.copy(m_pointers[pointer].current);
-}
-
-void CTouchInput::handleMultiTouchGesture()
-{
- handleZoomPinch();
- handleRotation();
-}
-
-void CTouchInput::handleZoomPinch()
-{
- Pointer& primaryPointer = m_pointers[0];
- Pointer& secondaryPointer = m_pointers[1];
-
- // 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);
- }
-}
-
-void CTouchInput::handleRotation()
-{
- Pointer& primaryPointer = m_pointers[0];
- Pointer& secondaryPointer = m_pointers[1];
-
- 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_fRotateAngle -= angle;
- else
- m_fRotateAngle += angle;
-
- OnRotate(centerX, centerY, m_fRotateAngle);
- }
- }
-}
-
-void CTouchInput::OnTimeout()
-{
- CSingleLock lock(m_critical);
-
- switch (m_gestureState)
- {
- case TouchGestureSingleTouch:
- setGestureState(TouchGestureSingleTouchHold);
-
- OnSingleTouchHold(m_pointers[0].down.x, m_pointers[0].down.y);
- OnSingleLongPress(m_pointers[0].down.x, m_pointers[0].down.y);
- 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);
- OnDoubleLongPress(m_pointers[0].down.x, m_pointers[0].down.y, m_pointers[1].down.x, m_pointers[1].down.y);
- }
- break;
-
- default:
- break;
- }
-}
-
-void CTouchInput::OnTouchAbort()
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnTouchAbort();
-}
-
-bool CTouchInput::OnSingleTouchStart(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnSingleTouchStart(x, y);
-
- return true;
-}
-
-bool CTouchInput::OnSingleTouchHold(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnSingleTouchHold(x, y);
-
- return true;
-}
-
-bool CTouchInput::OnSingleTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnSingleTouchMove(x, y, offsetX, offsetY, velocityX, velocityY);
-
- return true;
-}
-
-bool CTouchInput::OnSingleTouchEnd(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnSingleTouchEnd(x, y);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchStart(float x, float y, int32_t pointers /* = 2 */)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchStart(x, y, pointers);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchDown(float x, float y, int32_t pointer)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchDown(x, y, pointer);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchHold(float x, float y, int32_t pointers /* = 2 */)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchHold(x, y, pointers);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchMove(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY, int32_t pointer)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchMove(x, y, offsetX, offsetY, velocityX, velocityY, pointer);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchUp(float x, float y, int32_t pointer)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchUp(x, y, pointer);
-
- return true;
-}
-
-bool CTouchInput::OnMultiTouchEnd(float x, float y, int32_t pointers /* = 2 */)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnMultiTouchEnd(x, y, pointers);
-
- return true;
-}
-
-bool CTouchInput::OnTouchGesturePanStart(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnTouchGesturePanStart(x, y);
-
- return true;
-}
-
-bool CTouchInput::OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnTouchGesturePan(x, y, offsetX, offsetY, velocityX, velocityY);
-
- return true;
-}
-
-bool CTouchInput::OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- return m_handler->OnTouchGesturePanEnd(x, y, offsetX, offsetY, velocityX, velocityY);
-
- return true;
-}
-
-void CTouchInput::OnSingleTap(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnSingleTap(x, y);
-}
-
-void CTouchInput::OnSingleLongPress(float x, float y)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnSingleLongPress(x, y);
-}
-
-void CTouchInput::OnDoubleTap(float x1, float y1, float x2, float y2)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnDoubleTap(x1, y1, x2, y2);
-}
-
-void CTouchInput::OnDoubleLongPress(float x1, float y1, float x2, float y2)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnDoubleLongPress(x1, y1, x2, y2);
-}
-
-void CTouchInput::OnZoomPinch(float centerX, float centerY, float zoomFactor)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnZoomPinch(centerX, centerY, zoomFactor);
-}
-
-void CTouchInput::OnRotate(float centerX, float centerY, float angle)
-{
- CLog::Log(LOGDEBUG, "%s", __FUNCTION__);
-
- if (m_handler)
- m_handler->OnRotate(centerX, centerY, angle);
-}
View
428 xbmc/input/TouchInput.h
@@ -1,428 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2012-2013 Team XBMC
- * http://www.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 "threads/CriticalSection.h"
-#include "threads/Timer.h"
-#include "utils/Vector.h"
-
-#define TOUCH_MAX_POINTERS 2
-
-class ITouchHandler
-{
-public:
- virtual ~ITouchHandler() { }
-
- /*!
- \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 A multi touch gesture has started
-
- \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 OnMultiTouchStart(float x, float y, int32_t pointers = 2) { 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
- \sa OnDoubleLongPress
- */
- 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 multi touch gesture has ended (the last 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
- \param pointers The number of pointers involved (default 2)
- \return True if the event was handled otherwise false
- */
- virtual bool OnMultiTouchEnd(float x, float y, int32_t pointers = 2) { 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 OnTouchGesturePanStart(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 OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY) { return true; }
-
- // convenience events
- /*!
- \brief A tap with a single 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
- \return True if the event was handled otherwise false
- */
- virtual void OnSingleTap(float x, float y) { }
- /*!
- \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 OnSingleTouchHold
- */
- virtual void OnSingleLongPress(float x, float y) { }
- /*!
- \brief A tap with two simultaneous touches has been performed
-
- \param x1 The x coordinate (with sub-pixel) of the first touch
- \param y1 The y coordinate (with sub-pixel) of the first touch
- \param x2 The x coordinate (with sub-pixel) of the second touch
- \param y2 The y coordinate (with sub-pixel) of the second touch
- \return True if the event was handled otherwise false
- \sa
- */
- virtual void OnDoubleTap(float x1, float y1, float x2, float y2) { }
- /*!
- \brief Two simultaneous touches have been held down for a certain amount of time
-
- \param x1 The x coordinate (with sub-pixel) of the first touch
- \param y1 The y coordinate (with sub-pixel) of the first touch
- \param x2 The x coordinate (with sub-pixel) of the second touch
- \param y2 The y coordinate (with sub-pixel) of the second touch
- \return True if the event was handled otherwise false
- \sa OnMultiTouchHold
- */
- virtual void OnDoubleLongPress(float x1, float y1, float x2, float y2) { }
- /*!
- \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
- \sa
- */
- 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
- \sa
- */
- virtual void OnRotate(float centerX, float centerY, float angle) { }
-};
-
-class CTouchInput : private ITouchHandler, private ITimerCallback
-{
-public:
- typedef enum {
- TouchEventAbort,
- TouchEventDown,
- TouchEventUp,
- TouchEventMove
- } TouchEvent;
-
- /*!
- \brief Get an instance of the touch input manager
- */
- static CTouchInput &Get();
-
- /*!
- \brief Register a touch input handler
-
- There can only be one touch input handler
- active.
-
- \param touchHandler An instance of a touch handler implementing the ITouchHandler interface
- */
- void RegisterHandler(ITouchHandler *touchHandler);
- /*!
- \brief Unregister the touch handler
- */
- void UnregisterHandler();
-
- /*!
- \brief Set the timeout after which a touch turns into a touch hold
- \param timeout Timeout in milliseconds
- */
- void SetTouchHoldTimeout(int32_t timeout);
-
- /*!
- \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
- */
- bool Handle(TouchEvent event, float x, float y, int64_t time, int32_t pointer = 0, float size = 0.0f);
-
- /*!
- \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
- */
- bool Update(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
- CTouchInput();
- CTouchInput(const CTouchInput&);
- CTouchInput const& operator=(CTouchInput const&);
- virtual ~CTouchInput();
-
- void saveLastTouch();
-
- void handleMultiTouchGesture();
- void handleZoomPinch();
- void handleRotation();
-
- // implementation of ITimerCallback
- virtual void OnTimeout();
-
- // implementation of ITouchHandler
- 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 OnMultiTouchStart(float x, float y, int32_t pointers = 2);
- 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 OnMultiTouchEnd(float x, float y, int32_t pointers = 2);
-
- virtual bool OnTouchGesturePanStart(float x, float y);
- virtual bool OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY);
- virtual bool OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY);
-
- // convenience events
- virtual void OnSingleTap(float x, float y);
- virtual void OnSingleLongPress(float x, float y);
- virtual void OnDoubleTap(float x1, float y1, float x2, float y2);
- virtual void OnDoubleLongPress(float x1, float y1, float x2, float y2);
- virtual void OnZoomPinch(float centerX, float centerY, float zoomFactor);
- virtual void OnRotate(float centerX, float centerY, float angle);
-
- CCriticalSection m_critical;
-
- int32_t m_holdTimeout;
- ITouchHandler *m_handler;
- CTimer *m_holdTimer;
-
- float m_fRotateAngle;
-
- class Touch : public CVector {
- public:
- Touch() { reset(); }
- virtual ~Touch() { }
-
- virtual void reset() { CVector::reset(); time = -1; }
-
- bool valid() const { return x >= 0.0f && y >= 0.0f && time >= 0; }
- void copy(const Touch &other) { x = other.x; y = other.y; time = other.time; }
-
- int64_t time; // in nanoseconds
- };
-
- class Pointer {
- public:
- Pointer() { reset(); }
-
- bool valid() const { return down.valid(); }
- void reset() { down.reset(); last.reset(); moving = false; size = 0.0f; }
-
- bool velocity(float &velocityX, float &velocityY, bool fromLast = true)
- {
- Touch &from = last;
- if (!fromLast)
- from = down;
-
- velocityX = 0.0f; // number of pixels per second
- velocityY = 0.0f; // number of pixels per second
-
- int64_t timeDiff = current.time - from.time;
- if (timeDiff <= 0)
- return false;
-
- velocityX = ((current.x - from.x) * 1000000000) / timeDiff;
- velocityY = ((current.y - from.y) * 1000000000) / timeDiff;
- return true;
- }
-
- Touch down;
- Touch last;
- Touch current;
- bool moving;
- float size;
- };
-
- Pointer m_pointers[TOUCH_MAX_POINTERS];
-
- 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;
-
- TouchGestureState m_gestureState;
- TouchGestureState m_gestureStateOld;
-
- void setGestureState(TouchGestureState gestureState) { m_gestureStateOld = m_gestureState; m_gestureState = gestureState; }
-};
View
240 xbmc/input/touch/ITouchActionHandler.h
@@ -0,0 +1,240 @@
+#pragma once
+/*
+ * Copyright (C) 2012-2013 Team XBMC
+ * http://www.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) { }
+};
View
104 xbmc/input/touch/ITouchInputHandler.h
@@ -0,0 +1,104 @@
+#pragma once
+/*
+ * Copyright (C) 2013 Team XBMC
+ * http://www.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;
+};
View
155 xbmc/input/touch/ITouchInputHandling.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.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);
+}
View
87 xbmc/input/touch/ITouchInputHandling.h
@@ -0,0 +1,87 @@
+#pragma once
+/*
+ * Copyright (C) 2013 Team XBMC
+ * http://www.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