From e72409bf395e0e49879839d332fa7729e662039e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 27 Oct 2014 14:37:04 -0700 Subject: [PATCH] move TouchEvent out of EventTypes to its own file --- .../AbstractControllerScriptingInterface.h | 1 + libraries/script-engine/src/EventTypes.cpp | 195 +--------------- libraries/script-engine/src/EventTypes.h | 42 ---- libraries/script-engine/src/TouchEvent.cpp | 211 ++++++++++++++++++ libraries/script-engine/src/TouchEvent.h | 56 +++++ 5 files changed, 270 insertions(+), 235 deletions(-) create mode 100644 libraries/script-engine/src/TouchEvent.cpp create mode 100644 libraries/script-engine/src/TouchEvent.h diff --git a/libraries/script-engine/src/AbstractControllerScriptingInterface.h b/libraries/script-engine/src/AbstractControllerScriptingInterface.h index 050a555ff5..b594d07f3e 100644 --- a/libraries/script-engine/src/AbstractControllerScriptingInterface.h +++ b/libraries/script-engine/src/AbstractControllerScriptingInterface.h @@ -20,6 +20,7 @@ #include "EventTypes.h" #include "KeyEvent.h" #include "MouseEvent.h" +#include "TouchEvent.h" class AbstractInputController : public QObject { Q_OBJECT diff --git a/libraries/script-engine/src/EventTypes.cpp b/libraries/script-engine/src/EventTypes.cpp index e70e3302a5..0bb4d2fd9c 100644 --- a/libraries/script-engine/src/EventTypes.cpp +++ b/libraries/script-engine/src/EventTypes.cpp @@ -14,209 +14,18 @@ #include "KeyEvent.h" #include "MouseEvent.h" +#include "TouchEvent.h" #include "EventTypes.h" void registerEventTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, KeyEvent::toScriptValue, KeyEvent::fromScriptValue); qScriptRegisterMetaType(engine, MouseEvent::toScriptValue, MouseEvent::fromScriptValue); - qScriptRegisterMetaType(engine, touchEventToScriptValue, touchEventFromScriptValue); + qScriptRegisterMetaType(engine, TouchEvent::toScriptValue, TouchEvent::fromScriptValue); qScriptRegisterMetaType(engine, wheelEventToScriptValue, wheelEventFromScriptValue); qScriptRegisterMetaType(engine, spatialEventToScriptValue, spatialEventFromScriptValue); } -TouchEvent::TouchEvent() : - x(0.0f), - y(0.0f), - isPressed(false), - isMoved(false), - isStationary(false), - isReleased(false), - isShifted(false), - isControl(false), - isMeta(false), - isAlt(false), - touchPoints(0), - points(), - radius(0.0f), - isPinching(false), - isPinchOpening(false), - angles(), - angle(0.0f), - deltaAngle(0.0f), - isRotating(false), - rotating("none") -{ -}; - -TouchEvent::TouchEvent(const QTouchEvent& event) : - // these values are not set by initWithQTouchEvent() because they only apply to comparing to other events - isPinching(false), - isPinchOpening(false), - deltaAngle(0.0f), - isRotating(false), - rotating("none") -{ - initWithQTouchEvent(event); -} - -TouchEvent::TouchEvent(const QTouchEvent& event, const TouchEvent& other) { - initWithQTouchEvent(event); - calculateMetaAttributes(other); -} - -// returns the angle (in degrees) between two points (note: 0 degrees is 'east') -float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) { - glm::vec2 length = b - a; - float angle = DEGREES_PER_RADIAN * std::atan2(length.y, length.x); - if (angle < 0) { - angle += 360.0f; - }; - return angle; -} - -void TouchEvent::initWithQTouchEvent(const QTouchEvent& event) { - // convert the touch points into an average - const QList& tPoints = event.touchPoints(); - float touchAvgX = 0.0f; - float touchAvgY = 0.0f; - touchPoints = tPoints.count(); - if (touchPoints > 1) { - for (int i = 0; i < touchPoints; ++i) { - touchAvgX += tPoints[i].pos().x(); - touchAvgY += tPoints[i].pos().y(); - - // add it to our points vector - glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y()); - points << thisPoint; - } - touchAvgX /= (float)(touchPoints); - touchAvgY /= (float)(touchPoints); - } else { - // I'm not sure this should ever happen, why would Qt send us a touch event for only one point? - // maybe this happens in the case of a multi-touch where all but the last finger is released? - touchAvgX = tPoints[0].pos().x(); - touchAvgY = tPoints[0].pos().y(); - } - x = touchAvgX; - y = touchAvgY; - - // after calculating the center point (average touch point), determine the maximum radius - // also calculate the rotation angle for each point - float maxRadius = 0.0f; - glm::vec2 center(x,y); - for (int i = 0; i < touchPoints; ++i) { - glm::vec2 touchPoint(tPoints[i].pos().x(), tPoints[i].pos().y()); - float thisRadius = glm::distance(center,touchPoint); - if (thisRadius > maxRadius) { - maxRadius = thisRadius; - } - - // calculate the angle for this point - float thisAngle = angleBetweenPoints(center,touchPoint); - angles << thisAngle; - } - radius = maxRadius; - - // after calculating the angles for each touch point, determine the average angle - float totalAngle = 0.0f; - for (int i = 0; i < touchPoints; ++i) { - totalAngle += angles[i]; - } - angle = totalAngle/(float)touchPoints; - - isPressed = event.touchPointStates().testFlag(Qt::TouchPointPressed); - isMoved = event.touchPointStates().testFlag(Qt::TouchPointMoved); - isStationary = event.touchPointStates().testFlag(Qt::TouchPointStationary); - isReleased = event.touchPointStates().testFlag(Qt::TouchPointReleased); - - // keyboard modifiers - isShifted = event.modifiers().testFlag(Qt::ShiftModifier); - isMeta = event.modifiers().testFlag(Qt::MetaModifier); - isControl = event.modifiers().testFlag(Qt::ControlModifier); - isAlt = event.modifiers().testFlag(Qt::AltModifier); -} - -void TouchEvent::calculateMetaAttributes(const TouchEvent& other) { - // calculate comparative event attributes... - if (other.radius > radius) { - isPinching = true; - isPinchOpening = false; - } else if (other.radius < radius) { - isPinchOpening = true; - isPinching = false; - } else { - isPinching = other.isPinching; - isPinchOpening = other.isPinchOpening; - } - - // determine if the points are rotating... - // note: if the number of touch points change between events, then we don't consider ourselves to be rotating - if (touchPoints == other.touchPoints) { - deltaAngle = angle - other.angle; - if (other.angle < angle) { - isRotating = true; - rotating = "clockwise"; - } else if (other.angle > angle) { - isRotating = true; - rotating = "counterClockwise"; - } else { - isRotating = false; - rotating = "none"; - } - } else { - deltaAngle = 0.0f; - isRotating = false; - rotating = "none"; - } -} - - -QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& event) { - QScriptValue obj = engine->newObject(); - obj.setProperty("x", event.x); - obj.setProperty("y", event.y); - obj.setProperty("isPressed", event.isPressed); - obj.setProperty("isMoved", event.isMoved); - obj.setProperty("isStationary", event.isStationary); - obj.setProperty("isReleased", event.isReleased); - obj.setProperty("isShifted", event.isShifted); - obj.setProperty("isMeta", event.isMeta); - obj.setProperty("isControl", event.isControl); - obj.setProperty("isAlt", event.isAlt); - obj.setProperty("touchPoints", event.touchPoints); - - QScriptValue pointsObj = engine->newArray(); - int index = 0; - foreach (glm::vec2 point, event.points) { - QScriptValue thisPoint = vec2toScriptValue(engine, point); - pointsObj.setProperty(index, thisPoint); - index++; - } - obj.setProperty("points", pointsObj); - obj.setProperty("radius", event.radius); - obj.setProperty("isPinching", event.isPinching); - obj.setProperty("isPinchOpening", event.isPinchOpening); - - obj.setProperty("angle", event.angle); - obj.setProperty("deltaAngle", event.deltaAngle); - QScriptValue anglesObj = engine->newArray(); - index = 0; - foreach (float angle, event.angles) { - anglesObj.setProperty(index, angle); - index++; - } - obj.setProperty("angles", anglesObj); - - obj.setProperty("isRotating", event.isRotating); - obj.setProperty("rotating", event.rotating); - return obj; -} - -void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event) { - // nothing for now... -} - WheelEvent::WheelEvent() : x(0.0f), y(0.0f), diff --git a/libraries/script-engine/src/EventTypes.h b/libraries/script-engine/src/EventTypes.h index 0cec3fe20d..54c2934c42 100644 --- a/libraries/script-engine/src/EventTypes.h +++ b/libraries/script-engine/src/EventTypes.h @@ -12,50 +12,12 @@ #ifndef hifi_EventTypes_h #define hifi_EventTypes_h -#include #include #include -#include -#include #include - -class TouchEvent { -public: - TouchEvent(); - TouchEvent(const QTouchEvent& event); - TouchEvent(const QTouchEvent& event, const TouchEvent& other); - - float x; - float y; - bool isPressed; - bool isMoved; - bool isStationary; - bool isReleased; - bool isShifted; - bool isControl; - bool isMeta; - bool isAlt; - int touchPoints; - QVector points; - float radius; - bool isPinching; - bool isPinchOpening; - - // angles are in degrees - QVector angles; // angle from center to each point - float angle; // the average of the angles - float deltaAngle; // the change in average angle from last event - bool isRotating; - QString rotating; - -private: - void initWithQTouchEvent(const QTouchEvent& event); - void calculateMetaAttributes(const TouchEvent& other); -}; - class WheelEvent { public: WheelEvent(); @@ -86,16 +48,12 @@ public: private: }; -Q_DECLARE_METATYPE(TouchEvent) Q_DECLARE_METATYPE(WheelEvent) Q_DECLARE_METATYPE(SpatialEvent) void registerEventTypes(QScriptEngine* engine); -QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& event); -void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event); - QScriptValue wheelEventToScriptValue(QScriptEngine* engine, const WheelEvent& event); void wheelEventFromScriptValue(const QScriptValue& object, WheelEvent& event); diff --git a/libraries/script-engine/src/TouchEvent.cpp b/libraries/script-engine/src/TouchEvent.cpp new file mode 100644 index 0000000000..b1cbbc2f15 --- /dev/null +++ b/libraries/script-engine/src/TouchEvent.cpp @@ -0,0 +1,211 @@ +// +// TouchEvent.cpp +// script-engine/src +// +// Created by Stephen Birarda on 2014-10-27. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include +#include + +#include "TouchEvent.h" + +TouchEvent::TouchEvent() : + x(0.0f), + y(0.0f), + isPressed(false), + isMoved(false), + isStationary(false), + isReleased(false), + isShifted(false), + isControl(false), + isMeta(false), + isAlt(false), + touchPoints(0), + points(), + radius(0.0f), + isPinching(false), + isPinchOpening(false), + angles(), + angle(0.0f), + deltaAngle(0.0f), + isRotating(false), + rotating("none") +{ + +} + +TouchEvent::TouchEvent(const QTouchEvent& event) : + // these values are not set by initWithQTouchEvent() because they only apply to comparing to other events + isPinching(false), + isPinchOpening(false), + deltaAngle(0.0f), + isRotating(false), + rotating("none") +{ + initWithQTouchEvent(event); +} + +TouchEvent::TouchEvent(const QTouchEvent& event, const TouchEvent& other) { + initWithQTouchEvent(event); + calculateMetaAttributes(other); +} + +// returns the angle (in degrees) between two points (note: 0 degrees is 'east') +float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) { + glm::vec2 length = b - a; + float angle = DEGREES_PER_RADIAN * std::atan2(length.y, length.x); + if (angle < 0) { + angle += 360.0f; + }; + return angle; +} + +void TouchEvent::initWithQTouchEvent(const QTouchEvent& event) { + // convert the touch points into an average + const QList& tPoints = event.touchPoints(); + float touchAvgX = 0.0f; + float touchAvgY = 0.0f; + touchPoints = tPoints.count(); + if (touchPoints > 1) { + for (int i = 0; i < touchPoints; ++i) { + touchAvgX += tPoints[i].pos().x(); + touchAvgY += tPoints[i].pos().y(); + + // add it to our points vector + glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y()); + points << thisPoint; + } + touchAvgX /= (float)(touchPoints); + touchAvgY /= (float)(touchPoints); + } else { + // I'm not sure this should ever happen, why would Qt send us a touch event for only one point? + // maybe this happens in the case of a multi-touch where all but the last finger is released? + touchAvgX = tPoints[0].pos().x(); + touchAvgY = tPoints[0].pos().y(); + } + x = touchAvgX; + y = touchAvgY; + + // after calculating the center point (average touch point), determine the maximum radius + // also calculate the rotation angle for each point + float maxRadius = 0.0f; + glm::vec2 center(x,y); + for (int i = 0; i < touchPoints; ++i) { + glm::vec2 touchPoint(tPoints[i].pos().x(), tPoints[i].pos().y()); + float thisRadius = glm::distance(center,touchPoint); + if (thisRadius > maxRadius) { + maxRadius = thisRadius; + } + + // calculate the angle for this point + float thisAngle = angleBetweenPoints(center,touchPoint); + angles << thisAngle; + } + radius = maxRadius; + + // after calculating the angles for each touch point, determine the average angle + float totalAngle = 0.0f; + for (int i = 0; i < touchPoints; ++i) { + totalAngle += angles[i]; + } + angle = totalAngle/(float)touchPoints; + + isPressed = event.touchPointStates().testFlag(Qt::TouchPointPressed); + isMoved = event.touchPointStates().testFlag(Qt::TouchPointMoved); + isStationary = event.touchPointStates().testFlag(Qt::TouchPointStationary); + isReleased = event.touchPointStates().testFlag(Qt::TouchPointReleased); + + // keyboard modifiers + isShifted = event.modifiers().testFlag(Qt::ShiftModifier); + isMeta = event.modifiers().testFlag(Qt::MetaModifier); + isControl = event.modifiers().testFlag(Qt::ControlModifier); + isAlt = event.modifiers().testFlag(Qt::AltModifier); +} + +void TouchEvent::calculateMetaAttributes(const TouchEvent& other) { + // calculate comparative event attributes... + if (other.radius > radius) { + isPinching = true; + isPinchOpening = false; + } else if (other.radius < radius) { + isPinchOpening = true; + isPinching = false; + } else { + isPinching = other.isPinching; + isPinchOpening = other.isPinchOpening; + } + + // determine if the points are rotating... + // note: if the number of touch points change between events, then we don't consider ourselves to be rotating + if (touchPoints == other.touchPoints) { + deltaAngle = angle - other.angle; + if (other.angle < angle) { + isRotating = true; + rotating = "clockwise"; + } else if (other.angle > angle) { + isRotating = true; + rotating = "counterClockwise"; + } else { + isRotating = false; + rotating = "none"; + } + } else { + deltaAngle = 0.0f; + isRotating = false; + rotating = "none"; + } +} + +QScriptValue TouchEvent::toScriptValue(QScriptEngine* engine, const TouchEvent& event) { + QScriptValue obj = engine->newObject(); + obj.setProperty("x", event.x); + obj.setProperty("y", event.y); + obj.setProperty("isPressed", event.isPressed); + obj.setProperty("isMoved", event.isMoved); + obj.setProperty("isStationary", event.isStationary); + obj.setProperty("isReleased", event.isReleased); + obj.setProperty("isShifted", event.isShifted); + obj.setProperty("isMeta", event.isMeta); + obj.setProperty("isControl", event.isControl); + obj.setProperty("isAlt", event.isAlt); + obj.setProperty("touchPoints", event.touchPoints); + + QScriptValue pointsObj = engine->newArray(); + int index = 0; + foreach (glm::vec2 point, event.points) { + QScriptValue thisPoint = vec2toScriptValue(engine, point); + pointsObj.setProperty(index, thisPoint); + index++; + } + obj.setProperty("points", pointsObj); + obj.setProperty("radius", event.radius); + obj.setProperty("isPinching", event.isPinching); + obj.setProperty("isPinchOpening", event.isPinchOpening); + + obj.setProperty("angle", event.angle); + obj.setProperty("deltaAngle", event.deltaAngle); + QScriptValue anglesObj = engine->newArray(); + index = 0; + foreach (float angle, event.angles) { + anglesObj.setProperty(index, angle); + index++; + } + obj.setProperty("angles", anglesObj); + + obj.setProperty("isRotating", event.isRotating); + obj.setProperty("rotating", event.rotating); + return obj; +} + +void TouchEvent::fromScriptValue(const QScriptValue& object, TouchEvent& event) { + // nothing for now... +} diff --git a/libraries/script-engine/src/TouchEvent.h b/libraries/script-engine/src/TouchEvent.h new file mode 100644 index 0000000000..9c1147fecf --- /dev/null +++ b/libraries/script-engine/src/TouchEvent.h @@ -0,0 +1,56 @@ +// +// TouchEvent.h +// script-engine/src +// +// Created by Stephen Birarda on 2014-10-27. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_TouchEvent_h +#define hifi_TouchEvent_h + +#include + +class TouchEvent { +public: + TouchEvent(); + TouchEvent(const QTouchEvent& event); + TouchEvent(const QTouchEvent& event, const TouchEvent& other); + + static QScriptValue toScriptValue(QScriptEngine* engine, const TouchEvent& event); + static void fromScriptValue(const QScriptValue& object, TouchEvent& event); + + float x; + float y; + bool isPressed; + bool isMoved; + bool isStationary; + bool isReleased; + bool isShifted; + bool isControl; + bool isMeta; + bool isAlt; + int touchPoints; + QVector points; + float radius; + bool isPinching; + bool isPinchOpening; + + // angles are in degrees + QVector angles; // angle from center to each point + float angle; // the average of the angles + float deltaAngle; // the change in average angle from last event + bool isRotating; + QString rotating; + +private: + void initWithQTouchEvent(const QTouchEvent& event); + void calculateMetaAttributes(const TouchEvent& other); +}; + +Q_DECLARE_METATYPE(TouchEvent) + +#endif // hifi_TouchEvent_h \ No newline at end of file