implement pinch-to-zoom on board -- and do it in such a way that class

loader doesn't barf on older versions of the OS that don't provide the
necessary APIs.  Tested only on original Motorola Droid so far (and
emulator running 1.6, which is too old.)
This commit is contained in:
Andy2 2011-12-01 18:56:44 -08:00
parent b242d70029
commit 15503522f2
2 changed files with 126 additions and 2 deletions

View file

@ -0,0 +1,78 @@
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
/*
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
* rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.view.MotionEvent;
import android.util.FloatMath;
// DO NOT LOAD THIS on devices running prior to 2.0. It'll crash.
public class BoardMultiHandler implements BoardView.MultiHandlerIface {
private int m_lastSpacing = -1; // negative means not in use
private int m_threshhold;
public BoardMultiHandler( int threshhold )
{
m_threshhold = threshhold;
}
public int getSpacing( MotionEvent event )
{
int result;
if ( 1 == event.getPointerCount() ) {
result = -1;
} else {
float xx = event.getX( 0 ) - event.getX( 1 );
float yy = event.getY( 0 ) - event.getY( 1 );
result = (int)FloatMath.sqrt( (xx * xx) + (yy * yy) );
}
return result;
}
public boolean inactive()
{
return 0 > m_lastSpacing;
}
public void activate( MotionEvent event )
{
m_lastSpacing = getSpacing( event );
}
public void deactivate()
{
m_lastSpacing = -1;
}
public int figureZoom( MotionEvent event )
{
int zoomDir = 0;
if ( 0 <= m_lastSpacing ) {
int newSpacing = getSpacing( event );
int diff = Math.abs( newSpacing - m_lastSpacing );
if ( diff > m_threshhold ) {
zoomDir = newSpacing < m_lastSpacing? -1 : 1;
m_lastSpacing = newSpacing;
}
}
return zoomDir;
}
}

View file

@ -34,6 +34,7 @@ import android.view.MotionEvent;
import android.graphics.drawable.Drawable;
import android.content.res.Resources;
import android.graphics.Paint.FontMetricsInt;
import android.os.Build;
import android.os.Handler;
import java.nio.IntBuffer;
@ -41,10 +42,20 @@ import junit.framework.Assert;
public class BoardView extends View implements DrawCtx, BoardHandler,
SyncedDraw {
public interface MultiHandlerIface {
boolean inactive();
void activate( MotionEvent event );
void deactivate();
int figureZoom( MotionEvent event );
int getSpacing( MotionEvent event );
}
private static final float MIN_FONT_DIPS = 14.0f;
private static Bitmap s_bitmap; // the board
private static final int IN_TRADE_ALPHA = 0x3FFFFFFF;
private static final int PINCH_THRESHOLD = 40;
private Context m_context;
private Paint m_drawPaint;
@ -83,6 +94,8 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
private int m_pendingScore;
private Handler m_viewHandler;
private MultiHandlerIface m_multiHandler = null;
// FontDims: exists to translate space available to the largest
// font we can draw within that space taking advantage of our use
// being limited to a known small subset of glyphs. We need two
@ -168,6 +181,15 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
}
m_viewHandler = new Handler();
try {
int sdk_int = Integer.decode( Build.VERSION.SDK );
if ( sdk_int >= Build.VERSION_CODES.ECLAIR ) {
m_multiHandler = new BoardMultiHandler( PINCH_THRESHOLD );
} else {
Utils.logf( "OS version %d too old for multi-touch", sdk_int );
}
} catch ( Exception ex ) {}
}
@Override
@ -179,17 +201,41 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
switch ( action ) {
case MotionEvent.ACTION_DOWN:
if ( null != m_multiHandler ) {
m_multiHandler.deactivate();
}
m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_DOWN, xx, yy );
break;
case MotionEvent.ACTION_MOVE:
m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_MOVE, xx, yy );
if ( null == m_multiHandler || m_multiHandler.inactive() ) {
m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_MOVE, xx, yy );
} else {
int zoomBy = m_multiHandler.figureZoom( event );
if ( 0 != zoomBy ) {
m_jniThread.handle( JNIThread.JNICmd.CMD_ZOOM,
zoomBy < 0 ? -2 : 2 );
}
}
break;
case MotionEvent.ACTION_UP:
m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_UP, xx, yy );
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_2_DOWN:
if ( null != m_multiHandler ) {
m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_UP, xx, yy );
m_multiHandler.activate( event );
}
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_2_UP:
if ( null != m_multiHandler ) {
m_multiHandler.deactivate();
}
break;
default:
Utils.logf( "unknown action: %d", action );
Utils.logf( event.toString() );
break;
}
return true; // required to get subsequent events