/**
* Copyright (C) 2012 Iordan Iordanov
* Copyright (C) 2009 Michael A. MacDonald
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
package com.iiordanov.bVNC.input;
import com.iiordanov.bVNC.RemoteCanvas;
import com.iiordanov.bVNC.RemoteCanvasActivity;
import android.graphics.PointF;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
/**
* Handles panning the screen continuously over a period of time
* @author Michael A. MacDonald
*/
public class Panner implements Runnable {
RemoteCanvasActivity activity;
Handler handler;
PointF velocity;
long lastSent;
VelocityUpdater updater;
final int freq = 10;
private static final String TAG = "PANNER";
/**
* Specify how the panning velocity changes over time
* @author Michael A. MacDonald
*/
interface VelocityUpdater {
/**
* Called approximately every 50 ms to update the velocity of panning
* @param p X and Y components to update
* @param interval Milliseconds since last update
* @return False if the panning should stop immediately; true otherwise
*/
boolean updateVelocity(PointF p, long interval);
}
static class DefaultUpdater implements VelocityUpdater {
static DefaultUpdater instance = new DefaultUpdater();
/**
* Don't change velocity
*/
@Override
public boolean updateVelocity(PointF p, long interval) {
return true;
}
}
public Panner(RemoteCanvasActivity act, Handler hand) {
activity = act;
velocity = new PointF();
handler = hand;
}
public void stop() {
handler.removeCallbacks(this);
}
public void start(float xv, float yv, VelocityUpdater update) {
activity.getCanvas().bitmapData.drawable._defaultPaint.setFilterBitmap(false);
if (update == null)
update = DefaultUpdater.instance;
updater = update;
velocity.x = xv;
velocity.y = yv;
//Log.v(TAG, String.format("pan start %f %f", velocity.x, velocity.y));
lastSent = SystemClock.uptimeMillis();
handler.postDelayed(this, freq);
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
long interval = SystemClock.uptimeMillis() - lastSent;
lastSent += interval;
double scale = (double)interval / 50.0;
RemoteCanvas canvas = activity.getCanvas();
//Log.v(TAG, String.format("panning %f %d %d", scale, (int)((double)velocity.x * scale), (int)((double)velocity.y * scale)));
if ( canvas.pan((int)((double)velocity.x * scale), (int)((double)velocity.y * scale))) {
if (updater.updateVelocity(velocity, interval)) {
handler.postDelayed(this, freq);
} else {
canvas.bitmapData.drawable._defaultPaint.setFilterBitmap(true);
canvas.invalidate();
stop();
}
} else {
canvas.bitmapData.drawable._defaultPaint.setFilterBitmap(true);
canvas.invalidate();
stop();
}
}
}