/*
* Copyright (C) 2011 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.
*/
package com.android.talkback.contextmenu;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Detects long presses.
*/
class LongPressHandler extends Handler implements View.OnTouchListener {
private static final long LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
private static final int MSG_LONG_PRESS = 1;
private final int TOUCH_SLOP_SQUARED;
private LongPressListener mListener;
private MotionEvent mPreviousEvent;
private float mMoved;
/**
* Creates a new long press handler.
*
* @param context The parent context.
*/
public LongPressHandler(Context context) {
super(context.getMainLooper());
final int touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
TOUCH_SLOP_SQUARED = touchSlop * touchSlop;
}
/**
* Sets the listener that receives long press callbacks.
*
* @param listener The listener to set.
*/
public void setListener(LongPressListener listener) {
mListener = listener;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_HOVER_ENTER:
mMoved = 0;
//$FALL-THROUGH$
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_HOVER_MOVE:
if (mPreviousEvent != null) {
final float dX = event.getX() - mPreviousEvent.getX();
final float dY = event.getY() - mPreviousEvent.getY();
final float moved = (dX * dX) + (dY * dY);
mMoved += moved;
}
if (mMoved > TOUCH_SLOP_SQUARED) {
mMoved = 0;
removeMessages(MSG_LONG_PRESS);
final Message msg = obtainMessage(MSG_LONG_PRESS, mPreviousEvent);
sendMessageDelayed(msg, LONG_PRESS_TIMEOUT);
}
mPreviousEvent = MotionEvent.obtain(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_HOVER_EXIT:
removeMessages(MSG_LONG_PRESS);
if (mPreviousEvent != null) {
mPreviousEvent.recycle();
mPreviousEvent = null;
}
break;
}
return false;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LONG_PRESS:
if (mListener != null) {
mListener.onLongPress();
}
break;
}
}
/**
* Handles long press callbacks.
*/
public interface LongPressListener {
/**
* Called when a long press is detected.
*/
public void onLongPress();
}
}