blob: ed3c23c725ac81feb6ba2b07e69d2ccd7150b627 [file] [log] [blame]
/* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VR_GVR_CAPI_INCLUDE_GVR_GESTURE_H_
#define VR_GVR_CAPI_INCLUDE_GVR_GESTURE_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
#if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER)
#include <memory>
#endif
#include <stdint.h>
#include "vr/gvr/capi/include/gvr_controller.h"
#ifdef __cplusplus
extern "C" {
#endif
/// @defgroup Gesture Gesture C API
/// @brief
/// The Gesture C API allows clients to recognize touchpad and button
/// gestures from a controller. Disclaimer: This API is experimental and is
/// subject to changes.
///
/// If you are writing C++ code, you might prefer to use the C++ wrapper rather
/// than implement this C API directly.
///
/// If you are using multiple controllers, you will need to create multiple
/// gvr_gesture_context objects, one for each controller.
///
/// Example API usage:
///
/// Initialization:
///
/// // Create the gesture context.
/// gvr_gesture_context* context = gvr_gesture_context_create();
///
/// Usage:
///
/// // Get the controller state from client.
/// gvr_controller_state* controller_state = ...
///
/// // Detect the gestures.
/// gvr_gesture_update(context, controller_state);
///
/// // Get the number of detected gestures.
/// int num_gestures = gvr_gesture_get_count(context);
///
/// for (int i = 0; i < num_gestures; i ++) {
/// gvr_gesture* gesture_ptr = gvr_gesture_get(context, i);
/// switch (gvr_gesture_get_type(gesture_ptr)) {
/// case GVR_GESTURE_SWIPE:
/// // Handle swipe gesture.
/// break;
/// case GVR_GESTURE_SCROLL_START:
/// // Handle the start of a sequence of scroll gestures.
/// break;
/// case GVR_GESTURE_SCROLL_UPDATE:
/// // Handle an update in a sequence of scroll gestures.
/// break;
/// case GVR_GESTURE_SCROLL_END:
/// // Handle the end of a sequence of scroll gestures.
/// break;
/// default:
/// // Unexpected gesture type.
/// break;
/// }
/// }
///
/// @{
/// Gesture types.
typedef enum {
/// Finger moves quickly across the touch pad. This is a transient state that
/// is only true for a single frame.
GVR_GESTURE_SWIPE = 1,
/// Finger starts scrolling on touch pad. This is a transient state that is
/// only true for a single frame.
GVR_GESTURE_SCROLL_START = 2,
/// Finger is in the process of scrolling.
GVR_GESTURE_SCROLL_UPDATE = 3,
/// Finger stops scrolling. This is a transient state that is only true for a
/// single frame.
GVR_GESTURE_SCROLL_END = 4
} gvr_gesture_type;
/// Gesture directions.
typedef enum {
/// Finger moves up on the touch pad.
GVR_GESTURE_DIRECTION_UP = 1,
/// Finger moves down on the touch pad.
GVR_GESTURE_DIRECTION_DOWN = 2,
/// Finger moves left on the touch pad.
GVR_GESTURE_DIRECTION_LEFT = 3,
/// Finger moves right on the touch pad.
GVR_GESTURE_DIRECTION_RIGHT = 4
} gvr_gesture_direction;
/// Opaque handle to gesture context.
typedef struct gvr_gesture_context_ gvr_gesture_context;
/// Opaque handle to gesture.
typedef struct gvr_gesture_ gvr_gesture;
/// Creates and initializes a gesture context instance which can be used to
/// invoke the gesture API functions.
///
/// @return A pointer to the created gesture context instance.
gvr_gesture_context* gvr_gesture_context_create();
/// Destroys the gesture context.
///
/// @param context A pointer to a pointer to the gesture context instance. The
/// pointer will be set to null after destruction.
void gvr_gesture_context_destroy(gvr_gesture_context** context);
/// Restarts gesture detection. This should be used whenever the user does not
/// lift up the finger from the controller touchpad, but the gesture detection
/// needs to be restarted (e.g. the controller reticle moves from a
/// non-scrollable region to a scrollable region).
///
/// @param context A pointer to the gesture context instance.
void gvr_gesture_restart(gvr_gesture_context* context);
/// Updates the gesture context based on controller state.
///
/// @param controller_state A pointer to the controller state instance.
/// @param context A pointer to the gesture context instance.
void gvr_gesture_update(const gvr_controller_state* controller_state,
gvr_gesture_context* context);
/// Returns the number of gestures detected in previous gvr_gesture_update().
///
/// @param context A pointer to the gesture context instance.
/// @return The number of detected gestures.
int gvr_gesture_get_count(const gvr_gesture_context* context);
/// Returns the gesture with the given index.
/// The returned pointer remains valid only until the list is modified i.e. by
/// calling gvr_gesture_update() or gvr_gesture_context_destroy().
///
/// @param context A pointer to the gesture context instance.
/// @param index The index of the gesture to be returned.
/// @return A pointer to the gesture instance at the given index.
const gvr_gesture* gvr_gesture_get(const gvr_gesture_context* context,
int index);
/// Returns the type (swipe/scroll_start/scroll_update/scroll_end) of given
/// gesture.
///
/// @param gesture A pointer to the gesture instance.
/// @return The type of the given gesture.
gvr_gesture_type gvr_gesture_get_type(const gvr_gesture* gesture);
/// Returns the direction (up/down/left/right) of given gesture.
///
/// @param gesture A pointer to the gesture instance.
/// @return The direction of the given gesture.
gvr_gesture_direction gvr_gesture_get_direction(const gvr_gesture* gesture);
/// Returns the velocity (in normalized distance / second) of the given gesture,
/// where (0,0) is the top-left of the touchpad and (1,1) is the bottom right.
///
/// @param gesture A pointer to the gesture instance.
/// @return The velocity of the given gesture.
gvr_vec2f gvr_gesture_get_velocity(const gvr_gesture* gesture);
/// Returns the displacement (in touchpad unit) of given gesture.
///
/// @param gesture A pointer to the gesture instance.
/// @return The displacement of the given gesture.
gvr_vec2f gvr_gesture_get_displacement(const gvr_gesture* gesture);
/// Returns whether a long press on controller button has been detected.
///
/// @param controller_state A pointer to the controller state instance.
/// @param context A pointer to the gesture context instance.
/// @param button A controller button type.
/// @return Whether the given button has been long pressed.
bool gvr_get_button_long_press(const gvr_controller_state* controller_state,
const gvr_gesture_context* context,
gvr_controller_button button);
/// @}
#ifdef __cplusplus
} // extern "C"
#endif
// Convenience C++ wrapper.
#if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER)
namespace gvr {
typedef gvr_gesture_direction GestureDirection;
typedef gvr_gesture_type GestureType;
typedef gvr_gesture Gesture;
/// This is a convenience C++ wrapper for the Gesture C API.
///
/// This wrapper strategy prevents ABI compatibility issues between compilers
/// by ensuring that the interface between client code and the implementation
/// code in libgvr_gesture.so is a pure C interface. The translation from C++
/// calls to C calls provided by this wrapper runs entirely in the client's
/// binary and is compiled by the client's compiler.
///
/// If you are using multiple controllers, you will need to create multiple
/// GestureApi objects, one for each controller.
///
/// Methods in this class are only documented insofar as the C++ wrapping logic
/// is concerned; for information about the method itself, please refer to the
/// corresponding function in the C API.
///
/// Example API usage:
///
/// Initialization:
///
/// GestureApi gesture_api;
///
/// Usage:
///
/// // Get the controller state from client
/// ControllerState* controller_state = ...
///
/// // Detect the gestures.
/// gesture_api.Update(controller_state);
///
/// // Get the number of detected gestures
/// int num_gestures = gesture_api.GetGestureCount();
///
/// for (int i = 0; i < num_gestures; i ++) {
/// Gesture* gesture_ptr = gesture_api.GetGesture(i);
/// switch (gesture_api.GetGestureType(gesture_ptr)) {
/// case GVR_GESTURE_SWIPE:
/// // Handle swipe gesture.
/// break;
/// case GVR_GESTURE_SCROLL_START:
/// // Handle the start of a sequence of scroll gestures.
/// break;
/// case GVR_GESTURE_SCROLL_UPDATE:
/// // Handle an update in a sequence of scroll gestures.
/// break;
/// case GVR_GESTURE_SCROLL_END:
/// // Handle the end of a sequence of scroll gestures.
/// break;
/// default:
/// // Unexpected gesture type.
/// break;
/// }
/// }
///
class GestureApi
: public WrapperBase<gvr_gesture_context, gvr_gesture_context_destroy> {
public:
using WrapperBase::WrapperBase;
/// Creates a GestureApi object. It is properly initialized and can handle
/// gesture detection immediately.
GestureApi() : WrapperBase(gvr_gesture_context_create()) {}
/// Restarts gesture detection.
/// For more information, see gvr_gesture_restart().
void Restart() { gvr_gesture_restart(cobj()); }
/// Updates gesture context based on current controller state.
/// For more information, see gvr_gesture_update().
void Update(const ControllerState* controller_state) {
gvr_gesture_update(controller_state->cobj(), cobj());
}
/// Returns the number of gestures detected.
/// For more information, see gvr_gesture_get_count().
int GetGestureCount() { return gvr_gesture_get_count(cobj()); }
/// Returns the gesture at given index.
/// For more information, see gvr_gesture_get().
const Gesture* GetGesture(int index) {
return gvr_gesture_get(cobj(), index);
}
/// Returns the type of the given gesture.
/// For more information, see gvr_gesture_get_type().
GestureType GetGestureType(const Gesture* gesture) {
return gvr_gesture_get_type(gesture);
}
/// Returns the direction of current gesture.
/// For more information, see gvr_gesture_get_direction().
GestureDirection GetGestureDirection(const Gesture* gesture) {
return gvr_gesture_get_direction(gesture);
}
/// Returns gesture velocity.
/// For more information, see gvr_gesture_get_velocity().
gvr_vec2f GetVelocity(const Gesture* gesture) {
return gvr_gesture_get_velocity(gesture);
}
/// Returns gesture displacement.
/// For more information, see gvr_gesture_get_displacement().
gvr_vec2f GetDisplacement(const Gesture* gesture) {
return gvr_gesture_get_displacement(gesture);
}
/// Returns whether long press on the given controller button is detected.
/// For more information, see gvr_get_button_long_press().
bool GetButtonLongPress(const ControllerState* controller_state,
ControllerButton button) {
return gvr_get_button_long_press(controller_state->cobj(), cobj(),
button);
}
};
} // namespace gvr
#endif // #if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER)
#endif // VR_GVR_CAPI_INCLUDE_GVR_GESTURE_H_