[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / android / activity / AndroidTouch.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "AndroidTouch.h"
22 #include "XBMCApp.h"
23 #include "guilib/GUIWindowManager.h"
24 #include "windowing/WinEvents.h"
25 #include "ApplicationMessenger.h"
26
27 CAndroidTouch::CAndroidTouch() : m_dpi(160)
28 {
29   CTouchInput::Get().RegisterHandler(this);
30 }
31
32 CAndroidTouch::~CAndroidTouch()
33 {
34   CTouchInput::Get().UnregisterHandler();
35 }
36
37 bool CAndroidTouch::onTouchEvent(AInputEvent* event)
38 {
39   CXBMCApp::android_printf("%s", __PRETTY_FUNCTION__);
40   if (event == NULL)
41     return false;
42
43   size_t numPointers = AMotionEvent_getPointerCount(event);
44   if (numPointers <= 0)
45   {
46     CXBMCApp::android_printf(" => aborting touch event because there are no active pointers");
47     return false;
48   }
49
50   if (numPointers > TOUCH_MAX_POINTERS)
51     numPointers = TOUCH_MAX_POINTERS;
52
53   int32_t eventAction = AMotionEvent_getAction(event);
54   int8_t touchAction = eventAction & AMOTION_EVENT_ACTION_MASK;
55   size_t touchPointer = eventAction >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
56   
57   CTouchInput::TouchEvent touchEvent = CTouchInput::TouchEventAbort;
58   switch (touchAction)
59   {
60     case AMOTION_EVENT_ACTION_DOWN:
61     case AMOTION_EVENT_ACTION_POINTER_DOWN:
62       touchEvent = CTouchInput::TouchEventDown;
63       break;
64
65     case AMOTION_EVENT_ACTION_UP:
66     case AMOTION_EVENT_ACTION_POINTER_UP:
67       touchEvent = CTouchInput::TouchEventUp;
68       break;
69
70     case AMOTION_EVENT_ACTION_MOVE:
71       touchEvent = CTouchInput::TouchEventMove;
72       break;
73
74     case AMOTION_EVENT_ACTION_OUTSIDE:
75     case AMOTION_EVENT_ACTION_CANCEL:
76     default:
77       break;
78   }
79
80   float x = AMotionEvent_getX(event, touchPointer);
81   float y = AMotionEvent_getY(event, touchPointer);
82   float size = m_dpi / 16.0f;
83   int64_t time = AMotionEvent_getEventTime(event);
84
85   // first update all touch pointers
86   for (unsigned int pointer = 0; pointer < numPointers; pointer++)
87     CTouchInput::Get().Update(pointer, AMotionEvent_getX(event, pointer), AMotionEvent_getY(event, pointer),
88     AMotionEvent_getEventTime(event), m_dpi / 16.0f);
89
90   // now send the event
91   return CTouchInput::Get().Handle(touchEvent, x, y, time, touchPointer, size);
92 }
93
94 bool CAndroidTouch::OnSingleTouchStart(float x, float y)
95 {
96   // Send a mouse motion event for getting the current guiitem selected
97   XBMC_Touch(XBMC_MOUSEMOTION, 0, (uint16_t)x, (uint16_t)y);
98
99   return true;
100 }
101
102 bool CAndroidTouch::OnMultiTouchStart(float x, float y, int32_t pointers /* = 2 */)
103 {
104   XBMC_TouchGesture(ACTION_GESTURE_BEGIN, x, y, 0.0f, 0.0f);
105
106   return true;
107 }
108
109 bool CAndroidTouch::OnMultiTouchEnd(float x, float y, int32_t pointers /* = 2 */)
110 {
111   XBMC_TouchGesture(ACTION_GESTURE_END, 0.0f, 0.0f, 0.0f, 0.0f);
112
113   return true;
114 }
115
116 bool CAndroidTouch::OnTouchGesturePanStart(float x, float y)
117 {
118   XBMC_TouchGesture(ACTION_GESTURE_BEGIN, x, y, 0.0f, 0.0f);
119
120   return true;
121 }
122
123 bool CAndroidTouch::OnTouchGesturePan(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
124 {
125   XBMC_TouchGesture(ACTION_GESTURE_PAN, x, y, offsetX, offsetY);
126
127   return true;
128 }
129
130 bool CAndroidTouch::OnTouchGesturePanEnd(float x, float y, float offsetX, float offsetY, float velocityX, float velocityY)
131 {
132   XBMC_TouchGesture(ACTION_GESTURE_END, velocityX, velocityY, x, y);
133
134   // unfocus the focused GUI item
135   g_windowManager.SendMessage(GUI_MSG_UNFOCUS_ALL, 0, 0, 0, 0);
136
137   return true;
138 }
139
140 void CAndroidTouch::OnSingleTap(float x, float y)
141 {
142   XBMC_Touch(XBMC_MOUSEBUTTONDOWN, XBMC_BUTTON_LEFT, (uint16_t)x, (uint16_t)y);
143   XBMC_Touch(XBMC_MOUSEBUTTONUP, XBMC_BUTTON_LEFT, (uint16_t)x, (uint16_t)y);
144 }
145
146 void CAndroidTouch::OnSingleLongPress(float x, float y)
147 {
148   // we send a right-click for this
149   XBMC_Touch(XBMC_MOUSEBUTTONDOWN, XBMC_BUTTON_RIGHT, (uint16_t)x, (uint16_t)y);
150   XBMC_Touch(XBMC_MOUSEBUTTONUP,   XBMC_BUTTON_RIGHT, (uint16_t)x, (uint16_t)y);
151 }
152
153 void CAndroidTouch::OnZoomPinch(float centerX, float centerY, float zoomFactor)
154 {
155   XBMC_TouchGesture(ACTION_GESTURE_ZOOM, centerX, centerY, zoomFactor, 0);
156 }
157
158 void CAndroidTouch::OnRotate(float centerX, float centerY, float angle)
159 {
160   XBMC_TouchGesture(ACTION_GESTURE_ROTATE, centerX, centerY, angle, 0);
161 }
162
163 void CAndroidTouch::setDPI(uint32_t dpi)
164 {
165   if (dpi != 0)
166     m_dpi = dpi;
167 }
168
169 void CAndroidTouch::XBMC_Touch(uint8_t type, uint8_t button, uint16_t x, uint16_t y)
170 {
171   XBMC_Event newEvent;
172   memset(&newEvent, 0, sizeof(newEvent));
173   
174   newEvent.type = type;
175   newEvent.button.type = type;
176   newEvent.button.button = button;
177   newEvent.button.x = x;
178   newEvent.button.y = y;
179   
180   CXBMCApp::android_printf("XBMC_Touch(%u, %u, %u, %u)", type, button, x, y);
181   CWinEvents::MessagePush(&newEvent);
182 }
183
184 void CAndroidTouch::XBMC_TouchGesture(int32_t action, float posX, float posY, float offsetX, float offsetY)
185 {
186   CXBMCApp::android_printf("XBMC_TouchGesture(%d, %f, %f, %f, %f)", action, posX, posY, offsetX, offsetY);
187   if (action == ACTION_GESTURE_BEGIN)
188     CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, 0, 0), WINDOW_INVALID, false);
189   else if (action == ACTION_GESTURE_PAN)
190     CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, offsetY), WINDOW_INVALID, false);
191   else if (action == ACTION_GESTURE_END)
192     CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, offsetY), WINDOW_INVALID, false);
193   else if (action == ACTION_GESTURE_ZOOM || action == ACTION_GESTURE_ROTATE)
194     CApplicationMessenger::Get().SendAction(CAction(action, 0, posX, posY, offsetX, 0), WINDOW_INVALID, false);
195 }