CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/Input/GestureDetector.cpp
Views: 1401
// Unfinished.1// TODO:2// Zoom gesture a la http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/184734#include <cstring>56#include "Common/TimeUtil.h"7#include "Common/Input/GestureDetector.h"89const float estimatedInertiaDamping = 0.75f;1011GestureDetector::GestureDetector() {12memset(pointers, 0, sizeof(pointers));13}1415TouchInput GestureDetector::Update(const TouchInput &touch, const Bounds &bounds) {16if (touch.id < 0 || touch.id >= MAX_PTRS) {17return touch;18}19// Mouse / 1-finger-touch control.20Pointer &p = pointers[touch.id];21if ((touch.flags & TOUCH_DOWN) && bounds.Contains(touch.x, touch.y)) {22p.down = true;23p.downTime = time_now_d();24p.downX = touch.x;25p.downY = touch.y;26p.lastX = touch.x;27p.lastY = touch.y;28p.distanceX = 0.0f;29p.distanceY = 0.0f;30p.estimatedInertiaX = 0.0f;31p.estimatedInertiaY = 0.0f;32} else if (touch.flags & TOUCH_UP) {33p.down = false;34} else {35p.distanceX += fabsf(touch.x - p.lastX);36p.distanceY += fabsf(touch.y - p.lastY);3738p.estimatedInertiaX += touch.x - p.lastX;39p.estimatedInertiaY += touch.y - p.lastY;40p.estimatedInertiaX *= estimatedInertiaDamping;41p.estimatedInertiaY *= estimatedInertiaDamping;4243p.lastX = touch.x;44p.lastY = touch.y;45}4647if (p.distanceY > p.distanceX) {48if (p.down) {49double timeDown = time_now_d() - p.downTime;50if (!p.active && p.distanceY * timeDown > 3) {51p.active |= GESTURE_DRAG_VERTICAL;52// Kill the drag. TODO: Only cancel the drag in one direction.53TouchInput inp2 = touch;54inp2.flags = TOUCH_UP | TOUCH_CANCEL;55return inp2;56}57} else {58p.active = 0;59}60}6162if (p.distanceX > p.distanceY) {63if (p.down) {64double timeDown = time_now_d() - p.downTime;65if (!p.active && p.distanceX * timeDown > 3) {66p.active |= GESTURE_DRAG_HORIZONTAL;67// Kill the drag. TODO: Only cancel the drag in one direction.68TouchInput inp2 = touch;69inp2.flags = TOUCH_UP | TOUCH_CANCEL;70return inp2;71}72} else {73p.active = 0;74}75}7677return touch;78}7980void GestureDetector::UpdateFrame() {81for (int i = 0; i < MAX_PTRS; i++) {82pointers[i].estimatedInertiaX *= estimatedInertiaDamping;83pointers[i].estimatedInertiaY *= estimatedInertiaDamping;84}85}8687bool GestureDetector::IsGestureActive(Gesture gesture, int touchId) const {88if (touchId < 0 || touchId >= MAX_PTRS)89return false;90return (pointers[touchId].active & gesture) != 0;91}9293bool GestureDetector::GetGestureInfo(Gesture gesture, int touchId, float info[4]) const {94if (touchId < 0 || touchId >= MAX_PTRS)95return false;96memset(info, 0, sizeof(float) * 4);97if (!(pointers[touchId].active & gesture)) {98return false;99}100101switch (gesture) {102case GESTURE_DRAG_HORIZONTAL:103info[0] = pointers[touchId].lastX - pointers[touchId].downX;104info[1] = pointers[touchId].estimatedInertiaX;105return true;106case GESTURE_DRAG_VERTICAL:107info[0] = pointers[touchId].lastY - pointers[touchId].downY;108info[1] = pointers[touchId].estimatedInertiaY;109return true;110default:111return false;112}113}114115116