// ---------------------------------------------------------------------------
// jWebSocket - Copyright (c) 2010 Innotrade GmbH
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3 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 Lesser General Public License
// for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
// ---------------------------------------------------------------------------
package org.jwebsocket.android.demo;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.Timer;
import java.util.TimerTask;
import org.jwebsocket.api.WebSocketClientEvent;
import org.jwebsocket.api.WebSocketClientTokenListener;
import org.jwebsocket.api.WebSocketPacket;
import org.jwebsocket.kit.WebSocketException;
import org.jwebsocket.token.Token;
import org.jwebsocket.token.TokenFactory;
/**
*
* @author aschulze
*/
public class CanvasActivity extends Activity implements WebSocketClientTokenListener {
private RelativeLayout mLayout = null;
private Canvas lCanvas = null;
private Paint lPaint = null;
private String CANVAS_ID = "c1";
private float lSX = 0, lSY = 0;
private ImageView lImgView = null;
private ImageView lImgStatus = null;
int lWidth;
int lHeight;
Timer timer;
private boolean isDirty = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Create a LinearLayout in which to add the ImageView
mLayout = new RelativeLayout(this);
// get the display metric (width and height)
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
lWidth = metrics.widthPixels;
lHeight = metrics.heightPixels;
final Bitmap lBmp = Bitmap.createBitmap(lWidth, lHeight, Bitmap.Config.ARGB_8888);
lCanvas = new Canvas(lBmp);
// final ImageView lImgView = new ImageView(this);
lImgView = new ImageView(this);
lImgView.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lImgView.setImageBitmap(lBmp);
lImgView.setScaleType(ImageView.ScaleType.CENTER);
lImgView.setPadding(0, 0, 0, 0);
lImgStatus = new ImageView(this);
lImgStatus.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
lImgStatus.setImageResource(R.drawable.disconnected);
// lImgStatus.setAlpha(128);
final Paint lBck = new Paint();
lBck.setARGB(0xff, 0xff, 0xff, 0xff);
lCanvas.drawRect(0, 0, lWidth, lHeight, lBck);
lPaint = new Paint();
lPaint.setARGB(0xff, 0x00, 0x00, 0x00);
mLayout.addView(lImgView);
mLayout.addView(lImgStatus);
setContentView(mLayout);
lImgView.setOnTouchListener(new OnTouchListener() {
// start and end coordinates for a single line
float lSX, lSY, lEX, lEY;
public boolean onTouch(View aView, MotionEvent aME) {
Rect lRect = new Rect();
Window lWindow = getWindow();
lWindow.getDecorView().getWindowVisibleDisplayFrame(lRect);
int lStatusBarHeight = lRect.top;
int lContentViewTop =
lWindow.findViewById(Window.ID_ANDROID_CONTENT).getTop();
final int lTitleBarHeight = lContentViewTop - lStatusBarHeight;
int lAction = aME.getAction();
float lX = aME.getX();
float lY = aME.getY();
switch (lAction) {
case MotionEvent.ACTION_DOWN:
lEX = lX;
lEY = lY + lTitleBarHeight;
sendBeginPath(lEX, lEY);
break;
case MotionEvent.ACTION_MOVE:
lSX = lEX;
lSY = lEY;
lEX = lX;
lEY = lY + lTitleBarHeight;
lCanvas.drawLine(lSX, lSY, lEX, lEY, lPaint);
// updated by Alex 2010-08-10
sendLineTo(lEX, lEY);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
sendClosePath();
break;
}
lImgView.invalidate();
return true;
}
});
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (isDirty) {
lImgView.postInvalidate();
}
}
}, 0, 200);
}
// added by Alex: 2010-08-20
public void sendBeginPath(float ax, float ay) {
// use broadcast of system plug-in
// use namespace and type for server's broadcast "command"
Token lCanvasToken = TokenFactory.createToken(
"org.jwebsocket.plugins.system",
"broadcast");
// pass namespace and type
// for client's canvas "command"
lCanvasToken.setString("reqNS", "org.jwebsocket.plugins.canvas");
lCanvasToken.setString("reqType", "beginPath");
lCanvasToken.setDouble("x", ax);
lCanvasToken.setDouble("y", ay);
lCanvasToken.setString("id", CANVAS_ID);
try {
JWC.sendToken(lCanvasToken);
} catch (WebSocketException e) {
//TODO: log exception
}
}
public void sendLineTo(float aX, float aY) {
// added by Alex: 2010-08-20
// use broadcast of system plug-in
Token lCanvasToken = TokenFactory.createToken(
"org.jwebsocket.plugins.system",
"broadcast");
lCanvasToken.setString("reqNS", "org.jwebsocket.plugins.canvas");
lCanvasToken.setString("reqType", "lineTo");
lCanvasToken.setDouble("x", aX);
lCanvasToken.setDouble("y", aY);
lCanvasToken.setString("id", CANVAS_ID);
try {
JWC.sendToken(lCanvasToken);
} catch (WebSocketException ex) {
//TODO: log exception
}
}
// added by Alex: 2010-08-20
public void sendClosePath() {
// use broadcast of system plug-in
// use namespace and type for server's broadcast "command"
Token lCanvasToken = TokenFactory.createToken(
"org.jwebsocket.plugins.system",
"broadcast");
lCanvasToken.setString("id", CANVAS_ID);
// pass namespace and type
// for client's canvas "command"
lCanvasToken.setString("reqNS", "org.jwebsocket.plugins.canvas");
lCanvasToken.setString("reqType", "closePath");
try {
JWC.sendToken(lCanvasToken);
} catch (WebSocketException e) {
//TODO: log exception
}
}
@Override
public boolean onCreateOptionsMenu(Menu aMenu) {
MenuInflater lMenInfl = getMenuInflater();
lMenInfl.inflate(R.menu.canvas_menu, aMenu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.mniCanvasClear:
clearCanvas();
sendClear();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void clearCanvas() {
final Paint lBck = new Paint();
lBck.setARGB(0xff, 0xff, 0xff, 0xff);
lCanvas.drawRect(0, 0, lWidth, lHeight, lBck);
lImgView.invalidate();
}
private void sendClear() {
Token lCanvasToken = TokenFactory.createToken(
"org.jwebsocket.plugins.system",
"broadcast");
lCanvasToken.setString("id", CANVAS_ID);
// pass namespace and type
// for client's canvas "command"
lCanvasToken.setString("reqNS", "org.jwebsocket.plugins.canvas");
lCanvasToken.setString("reqType", "clear");
try {
JWC.sendToken(lCanvasToken);
} catch (WebSocketException e) {
//TODO: log exception
}
}
@Override
protected void onResume() {
super.onResume();
try {
// get the display metric (width and height)
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
lWidth = metrics.widthPixels;
lHeight = metrics.heightPixels;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(lWidth - 18, 2, 0, 0);
lImgStatus.setLayoutParams(lp);
JWC.addListener(this);
JWC.open();
} catch (WebSocketException ex) {
//TODO: log exception
}
}
@Override
protected void onPause() {
super.onPause();
try {
JWC.removeListener(this);
JWC.close();
} catch (WebSocketException ex) {
//TODO: log exception
}
}
public void processToken(WebSocketClientEvent aEvent, Token aToken) {
// check if incoming token is targetted to canvas (by name space)
if ("org.jwebsocket.plugins.canvas".equals(aToken.getString("reqNS"))) {
// check "beginPath" request
if ("beginPath".equals(aToken.getString("reqType"))) {
// nothing to do here
} else if ("moveTo".equals(aToken.getString("reqType"))) {
// keep start position "in mind"
lSX = new Float(aToken.getDouble("x", 0.0));
lSY = new Float(aToken.getDouble("y", 0.0));
// check "lineTo" request
} else if ("lineTo".equals(aToken.getString("reqType"))) {
// TODO: implement multiple canvas, this is what is used for
// int id = aToken.getInteger("identifier");
// if (id != getTaskId()) {
float lEX = new Float(aToken.getDouble("x", 0.0));
float lEY = new Float(aToken.getDouble("y", 0.0));
// draw the line
lCanvas.drawLine(lSX, lSY, lEX, lEY, lPaint);
// invalidate image view to re-draw the canvas
isDirty = true;
lSX = lEX;
lSY = lEY;
// }
// check "closePath" request
} else if ("line".equals(aToken.getString("reqType"))) {
// TODO: implement multiple canvas, this is what is used for
// int id = aToken.getInteger("identifier");
// if (id != getTaskId()) {
lSX = new Float(aToken.getDouble("x1", 0.0));
lSY = new Float(aToken.getDouble("y1", 0.0));
float lEX = new Float(aToken.getDouble("x2", 0.0));
float lEY = new Float(aToken.getDouble("y2", 0.0));
// draw the line
lCanvas.drawLine(lSX, lSY, lEX, lEY, lPaint);
// invalidate image view to re-draw the canvas
isDirty = true;
lSX = lEX;
lSY = lEY;
// }
// check "closePath" request
} else if ("closePath".equals(aToken.getString("reqType"))) {
// nothing to do here
} else if ("clear".equals(aToken.getString("reqType"))) {
clearCanvas();
}
}
}
public void processOpened(WebSocketClientEvent aEvent) {
// lImgStatus = (ImageView) findViewById(R.id.cameraImgStatus);
if (lImgStatus != null) {
// TODO: in fact it is only connected, not yet authenticated!
lImgStatus.setImageResource(R.drawable.authenticated);
}
}
public void processPacket(WebSocketClientEvent aEvent, WebSocketPacket aPacket) {
}
public void processClosed(WebSocketClientEvent aEvent) {
// lImgStatus = (ImageView) findViewById(R.id.cameraImgStatus);
if (lImgStatus != null) {
lImgStatus.setImageResource(R.drawable.disconnected);
}
}
}