Android Build Tools
This commit is contained in:
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright 2013 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "gestureDetector.h"
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// gestureDetector.cpp
|
||||
//--------------------------------------------------------------------------------
|
||||
namespace ndk_helper
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// includes
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// GestureDetector
|
||||
//--------------------------------------------------------------------------------
|
||||
GestureDetector::GestureDetector()
|
||||
{
|
||||
dp_factor_ = 1.f;
|
||||
}
|
||||
|
||||
void GestureDetector::SetConfiguration( AConfiguration* config )
|
||||
{
|
||||
dp_factor_ = 160.f / AConfiguration_getDensity( config );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// TapDetector
|
||||
//--------------------------------------------------------------------------------
|
||||
GESTURE_STATE TapDetector::Detect( const AInputEvent* motion_event )
|
||||
{
|
||||
if( AMotionEvent_getPointerCount( motion_event ) > 1 )
|
||||
{
|
||||
//Only support single touch
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t action = AMotionEvent_getAction( motion_event );
|
||||
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
switch( flags )
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
down_pointer_id_ = AMotionEvent_getPointerId( motion_event, 0 );
|
||||
down_x_ = AMotionEvent_getX( motion_event, 0 );
|
||||
down_y_ = AMotionEvent_getY( motion_event, 0 );
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
int64_t eventTime = AMotionEvent_getEventTime( motion_event );
|
||||
int64_t downTime = AMotionEvent_getDownTime( motion_event );
|
||||
if( eventTime - downTime <= TAP_TIMEOUT )
|
||||
{
|
||||
if( down_pointer_id_ == AMotionEvent_getPointerId( motion_event, 0 ) )
|
||||
{
|
||||
float x = AMotionEvent_getX( motion_event, 0 ) - down_x_;
|
||||
float y = AMotionEvent_getY( motion_event, 0 ) - down_y_;
|
||||
if( x * x + y * y < TOUCH_SLOP * TOUCH_SLOP * dp_factor_ )
|
||||
{
|
||||
LOGI( "TapDetector: Tap detected" );
|
||||
return GESTURE_STATE_ACTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return GESTURE_STATE_NONE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// DoubletapDetector
|
||||
//--------------------------------------------------------------------------------
|
||||
GESTURE_STATE DoubletapDetector::Detect( const AInputEvent* motion_event )
|
||||
{
|
||||
if( AMotionEvent_getPointerCount( motion_event ) > 1 )
|
||||
{
|
||||
//Only support single double tap
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tap_detected = tap_detector_.Detect( motion_event );
|
||||
|
||||
int32_t action = AMotionEvent_getAction( motion_event );
|
||||
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
switch( flags )
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
{
|
||||
int64_t eventTime = AMotionEvent_getEventTime( motion_event );
|
||||
if( eventTime - last_tap_time_ <= DOUBLE_TAP_TIMEOUT )
|
||||
{
|
||||
float x = AMotionEvent_getX( motion_event, 0 ) - last_tap_x_;
|
||||
float y = AMotionEvent_getY( motion_event, 0 ) - last_tap_y_;
|
||||
if( x * x + y * y < DOUBLE_TAP_SLOP * DOUBLE_TAP_SLOP * dp_factor_ )
|
||||
{
|
||||
LOGI( "DoubletapDetector: Doubletap detected" );
|
||||
return GESTURE_STATE_ACTION;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
if( tap_detected )
|
||||
{
|
||||
last_tap_time_ = AMotionEvent_getEventTime( motion_event );
|
||||
last_tap_x_ = AMotionEvent_getX( motion_event, 0 );
|
||||
last_tap_y_ = AMotionEvent_getY( motion_event, 0 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return GESTURE_STATE_NONE;
|
||||
}
|
||||
|
||||
void DoubletapDetector::SetConfiguration( AConfiguration* config )
|
||||
{
|
||||
dp_factor_ = 160.f / AConfiguration_getDensity( config );
|
||||
tap_detector_.SetConfiguration( config );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// PinchDetector
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
int32_t PinchDetector::FindIndex( const AInputEvent* event, int32_t id )
|
||||
{
|
||||
int32_t count = AMotionEvent_getPointerCount( event );
|
||||
for( uint32_t i = 0; i < count; ++i )
|
||||
{
|
||||
if( id == AMotionEvent_getPointerId( event, i ) )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
GESTURE_STATE PinchDetector::Detect( const AInputEvent* event )
|
||||
{
|
||||
GESTURE_STATE ret = GESTURE_STATE_NONE;
|
||||
int32_t action = AMotionEvent_getAction( event );
|
||||
uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
event_ = event;
|
||||
|
||||
int32_t count = AMotionEvent_getPointerCount( event );
|
||||
switch( flags )
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
vec_pointers_.push_back( AMotionEvent_getPointerId( event, 0 ) );
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN:
|
||||
{
|
||||
int32_t iIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
|
||||
>> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
vec_pointers_.push_back( AMotionEvent_getPointerId( event, iIndex ) );
|
||||
if( count == 2 )
|
||||
{
|
||||
//Start new pinch
|
||||
ret = GESTURE_STATE_START;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
vec_pointers_.pop_back();
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_UP:
|
||||
{
|
||||
int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
|
||||
>> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
int32_t released_pointer_id = AMotionEvent_getPointerId( event, index );
|
||||
|
||||
std::vector<int32_t>::iterator it = vec_pointers_.begin();
|
||||
std::vector<int32_t>::iterator it_end = vec_pointers_.end();
|
||||
int32_t i = 0;
|
||||
for( ; it != it_end; ++it, ++i )
|
||||
{
|
||||
if( *it == released_pointer_id )
|
||||
{
|
||||
vec_pointers_.erase( it );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i <= 1 )
|
||||
{
|
||||
//Reset pinch or drag
|
||||
if( count != 2 )
|
||||
{
|
||||
//Start new pinch
|
||||
ret = GESTURE_STATE_START | GESTURE_STATE_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
switch( count )
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
//Multi touch
|
||||
ret = GESTURE_STATE_MOVE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_CANCEL:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PinchDetector::GetPointers( Vec2& v1, Vec2& v2 )
|
||||
{
|
||||
if( vec_pointers_.size() < 2 )
|
||||
return false;
|
||||
|
||||
int32_t index = FindIndex( event_, vec_pointers_[0] );
|
||||
if( index == -1 )
|
||||
return false;
|
||||
|
||||
float x = AMotionEvent_getX( event_, index );
|
||||
float y = AMotionEvent_getY( event_, index );
|
||||
|
||||
index = FindIndex( event_, vec_pointers_[1] );
|
||||
if( index == -1 )
|
||||
return false;
|
||||
|
||||
float x2 = AMotionEvent_getX( event_, index );
|
||||
float y2 = AMotionEvent_getY( event_, index );
|
||||
|
||||
v1 = Vec2( x, y );
|
||||
v2 = Vec2( x2, y2 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// DragDetector
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
int32_t DragDetector::FindIndex( const AInputEvent* event, int32_t id )
|
||||
{
|
||||
int32_t count = AMotionEvent_getPointerCount( event );
|
||||
for( uint32_t i = 0; i < count; ++i )
|
||||
{
|
||||
if( id == AMotionEvent_getPointerId( event, i ) )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
GESTURE_STATE DragDetector::Detect( const AInputEvent* event )
|
||||
{
|
||||
GESTURE_STATE ret = GESTURE_STATE_NONE;
|
||||
int32_t action = AMotionEvent_getAction( event );
|
||||
int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
|
||||
>> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
event_ = event;
|
||||
|
||||
int32_t count = AMotionEvent_getPointerCount( event );
|
||||
switch( flags )
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
vec_pointers_.push_back( AMotionEvent_getPointerId( event, 0 ) );
|
||||
ret = GESTURE_STATE_START;
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN:
|
||||
vec_pointers_.push_back( AMotionEvent_getPointerId( event, index ) );
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
vec_pointers_.pop_back();
|
||||
ret = GESTURE_STATE_END;
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_UP:
|
||||
{
|
||||
int32_t released_pointer_id = AMotionEvent_getPointerId( event, index );
|
||||
|
||||
std::vector<int32_t>::iterator it = vec_pointers_.begin();
|
||||
std::vector<int32_t>::iterator it_end = vec_pointers_.end();
|
||||
int32_t i = 0;
|
||||
for( ; it != it_end; ++it, ++i )
|
||||
{
|
||||
if( *it == released_pointer_id )
|
||||
{
|
||||
vec_pointers_.erase( it );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i <= 1 )
|
||||
{
|
||||
//Reset pinch or drag
|
||||
if( count == 2 )
|
||||
{
|
||||
ret = GESTURE_STATE_START;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
switch( count )
|
||||
{
|
||||
case 1:
|
||||
//Drag
|
||||
ret = GESTURE_STATE_MOVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_CANCEL:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DragDetector::GetPointer( Vec2& v )
|
||||
{
|
||||
if( vec_pointers_.size() < 1 )
|
||||
return false;
|
||||
|
||||
int32_t iIndex = FindIndex( event_, vec_pointers_[0] );
|
||||
if( iIndex == -1 )
|
||||
return false;
|
||||
|
||||
float x = AMotionEvent_getX( event_, iIndex );
|
||||
float y = AMotionEvent_getY( event_, iIndex );
|
||||
|
||||
v = Vec2( x, y );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace ndkHelper
|
||||
|
||||
Reference in New Issue
Block a user