/*******************************************************************************
* Copyright 2013-2015 alladin-IT GmbH
*
* 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 at.alladin.rmbt.android.test;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import at.alladin.openrmbt.android.R;
import at.alladin.rmbt.android.util.InformationCollector;
import at.alladin.rmbt.client.helper.TestStatus;
public class TestView extends View
{
public final static int POS_PING_Y = 78;
public final static int POS_DOWN_Y = 115;
public final static int POS_UP_Y = 152;
private boolean recycled;
private final Bitmap genBackgroundBitmap;
private float scale = 1f;
private final int internalPaddingLeft;
private final int internalPaddingTop;
// private final Bitmap reflectionBitmap;
// private final float reflectionX;
// private final float reflectionY;
// private final Bitmap resultBackgroundBitmap;
private final Bitmap speedStatusDownBitmap;
private final Bitmap speedStatusUpBitmap;
private final int width;
private final int height;
private final Gauge speedGauge;
private final Gauge progressGauge;
private final Gauge signalGauge;
// private final float resultBgX;
// private final float resultBgY;
private final float speedStatusDownX;
private final float speedStatusDownY;
private final float speedStatusUpX;
private final float speedStatusUpY;
private final Paint bitmapPaint;
private final Paint headerPaint;
private final Paint resultPaint;
private final Paint progressPaint;
private final Paint signalPaint;
private final float headerX;
private final float headerY;
private final float subHeaderX;
private final float subHeaderY;
private final float resultPingX;
private final float resultPingY;
private final float resultDownX;
private final float resultDownY;
private final float resultUpX;
private final float resultUpY;
private final float progressX;
private final float progressY;
private final float signalX;
private final float signalY;
private String headerString;
private String subHeaderString;
private String progressString;
private String signalString;
private int signalType = InformationCollector.SINGAL_TYPE_NO_SIGNAL;
private String resultPingString;
private String resultDownString;
private String resultUpString;
private TestStatus testStatus;
private float signalRingX;
private float signalRingY;
private Bitmap signalRingBitmapMobile;
private Bitmap signalRingBitmapRsrp;
private Bitmap signalRingBitmapWlan;
private String signalDescriptionString;
private float signalDescriptionX;
private float signalDescriptionY;
private Paint signalDescriptionPaint;
private Bitmap signalStatusBgBitmap;
private float signalStatusBgX;
private float signalStatusBgY;
public TestView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
// scale = attrs.getAttributeFloatValue(null, "scale", 1f);
final Resources res = context.getResources();
bitmapPaint = new Paint();
bitmapPaint.setFilterBitmap(true);
final Bitmap backgroundBitmap = getBitmap(res,R.drawable.test_box_large);
width = backgroundBitmap.getWidth();
height = backgroundBitmap.getHeight();
final int relW = 610;
final int relH = 560;
internalPaddingLeft = coordW(18, relW);
internalPaddingTop = coordW(-30, relH);
final Bitmap speedRingBitmap = getBitmap(res, R.drawable.ringskala_speed);
final float speedRingX = coordFW(114, relW);
final float speedRingY = coordFH(285, relH);
final Bitmap speedStatusBgBitmap = getBitmap(res, R.drawable.statuscircles_speed);
final float speedStatusBgX = coordFW(127, relW);
final float speedStatusBgY = coordFH(312, relH);
final Bitmap progressRingBitmap = getBitmap(res, R.drawable.ringskala_progress);
final float progressRingX = coordFW(292, relW);
final float progressRingY = coordFH(89, relH);
final Bitmap progressStatusBgBitmap = getBitmap(res, R.drawable.statuscircles_progress);
final float progressStatusBgX = coordFW(320, relW);
final float progressStatusBgY = coordFH(125, relH);
signalRingBitmapMobile = getBitmap(res, R.drawable.ringskala_signal_mobile);
signalRingBitmapRsrp = getBitmap(res, R.drawable.ringskala_signal_rsrp);
signalRingBitmapWlan = getBitmap(res, R.drawable.ringskala_signal_wlan);
signalRingX = coordFW(382, relW);
signalRingY = coordFH(348, relH);
signalStatusBgBitmap = getBitmap(res, R.drawable.statuscircles_signal);
signalStatusBgX = coordFW(370, relW);
signalStatusBgY = coordFH(344, relH);
speedStatusDownBitmap = getBitmap(res, R.drawable.statuscircles_speed_download);
speedStatusDownX = coordFW(194, relW);
speedStatusDownY = coordFH(354, relH);
speedStatusUpBitmap = getBitmap(res, R.drawable.statuscircles_speed_upload);
speedStatusUpX = coordFW(194, relW);
speedStatusUpY = coordFH(349, relH);
genBackgroundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(genBackgroundBitmap);
//canvas.drawBitmap(backgroundBitmap, 0, 0, bitmapPaint);
//canvas.drawBitmap(resultBackgroundBitmap, resultBgX, resultBgY, bitmapPaint);
//if (! isInEditMode())
// backgroundBitmap.recycle();
canvas.drawBitmap(speedRingBitmap, speedRingX, speedRingY, bitmapPaint);
speedRingBitmap.recycle();
canvas.drawBitmap(speedStatusBgBitmap, speedStatusBgX, speedStatusBgY , bitmapPaint);
speedStatusBgBitmap.recycle();
canvas.drawBitmap(progressRingBitmap, progressRingX, progressRingY, bitmapPaint);
progressRingBitmap.recycle();
canvas.drawBitmap(progressStatusBgBitmap, progressStatusBgX, progressStatusBgY, bitmapPaint);
progressStatusBgBitmap.recycle();
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setFakeBoldText(true);
paint.setColor(Color.parseColor("#ffffff"));
paint.setTextSize(coordFH(23, relH));
paint.setTextAlign(Align.LEFT);
canvas.drawText("Ping:", coordFW(20, relW), coordFH(POS_PING_Y, relH), paint);
canvas.drawText("Down:", coordFW(20, relW), coordFH(POS_DOWN_Y, relH), paint);
canvas.drawText("Up:", coordFW(20, relW), coordFH(POS_UP_Y, relH), paint);
paint.setColor(Color.parseColor("#32c90e"));
paint.setTextAlign(Align.CENTER);
paint.setTextSize(coordFH(14, relH));
canvas.drawText(res.getString(R.string.test_mbps), coordFW(216, relW), coordFH(418, relH), paint);
paint.setColor(Color.parseColor("#ffa200"));
signalDescriptionString = res.getString(R.string.test_dbm);
signalDescriptionX = coordFW(432, relW);
signalDescriptionY = coordFH(427, relH);
signalDescriptionPaint = paint;
Bitmap background, dynamic, foreground;
int ih, iw, x, y;
background = getBitmap(res, R.drawable.test_gauge_speed_background);
dynamic = getBitmap(res, R.drawable.test_gauge_speed_dynamic);
foreground = getBitmap(res, R.drawable.test_gauge_speed_foreground);
speedGauge = new Gauge(2f, 302.38f, background, dynamic, foreground, 17f / 325, 18f / 325, 302f / 325,
303f / 325);
iw = speedGauge.getIntrinsicWidth();
ih = speedGauge.getIntrinsicHeight();
x = coordW(56, 610);
y = coordH(228, 560);
speedGauge.setBounds(x, y, x + iw, y + ih);
background = getBitmap(res, R.drawable.test_gauge_progress_background);
dynamic = getBitmap(res, R.drawable.test_gauge_progress_dynamic);
foreground = getBitmap(res, R.drawable.test_gauge_progress_foreground);
progressGauge = new Gauge(210f, 270f, background, dynamic, foreground, -2 / 300, 16f / 318, 280f / 300,
298f / 318);
iw = progressGauge.getIntrinsicWidth();
ih = progressGauge.getIntrinsicHeight();
x = coordW(247, 610);
y = coordH(33, 560);
progressGauge.setBounds(x, y, x + iw, y + ih);
background = getBitmap(res, R.drawable.test_gauge_signal_background);
dynamic = getBitmap(res, R.drawable.test_gauge_signal_dynamic);
foreground = getBitmap(res, R.drawable.test_gauge_signal_foreground);
signalGauge = new Gauge(118.75f, -155.88f, background, dynamic, foreground, -46 / 201f, -32 / 215f, 183 / 201f,
197 / 215f);
iw = signalGauge.getIntrinsicWidth();
ih = signalGauge.getIntrinsicHeight();
x = coordW(364, 610);
y = coordH(322, 560);
signalGauge.setBounds(x, y, x + iw, y + ih);
resultPaint = new Paint();
resultPaint.setAntiAlias(true);
resultPaint.setLinearText(true);
resultPaint.setTypeface(Typeface.DEFAULT_BOLD);
resultPaint.setColor(Color.parseColor("#ffffff")); //#002c44
resultPaint.setTextSize(coordFH(23, relH));
resultPaint.setTextAlign(Align.LEFT);
progressPaint = new Paint(resultPaint);
progressPaint.setColor(Color.WHITE);
progressPaint.setTextSize(coordFH(30, relH));
progressPaint.setTextAlign(Align.CENTER);
signalPaint = new Paint(progressPaint);
signalPaint.setTextSize(coordFH(20, relH));
headerPaint = new Paint(resultPaint);
headerPaint.setTextSize(coordFH(19, relH));
headerX = coordFW(10, relW);
headerY = coordFH(relH + 10, relH); //33
subHeaderX = coordFW(relW - 20, relW);
subHeaderY = coordFH(relH + 10, relH); //60
resultPingX = coordFW(90, relW);
resultPingY = coordFH(POS_PING_Y, relH);
resultDownX = coordFW(90, relW);
resultDownY = coordFH(POS_DOWN_Y, relH);
resultUpX = coordFW(90, relW);
resultUpY = coordFH(POS_UP_Y, relH);
progressX = coordFW(386, relW);
progressY = coordFH(203, relH);
signalX = coordFW(427, relW);
signalY = coordFH(409, relH);
}
protected Bitmap getBitmap(Resources res, int id)
{
return BitmapFactory.decodeResource(res, id);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
final int paddingH = getPaddingLeft() + internalPaddingLeft + getPaddingRight();
final int paddingW = getPaddingTop() + internalPaddingTop + getPaddingBottom();
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int w = MeasureSpec.getSize(widthMeasureSpec);
final int newW = width + paddingH;
switch (MeasureSpec.getMode(widthMeasureSpec))
{
case MeasureSpec.AT_MOST:
if (newW < w)
w = newW;
break;
case MeasureSpec.EXACTLY:
break;
case MeasureSpec.UNSPECIFIED:
w = newW;
break;
}
scale = (float) (w - getPaddingLeft() - getPaddingRight()) / (width + internalPaddingLeft);
int h = MeasureSpec.getSize(heightMeasureSpec);
final int newH = Math.round((height + 20) * scale) + paddingW;
switch (MeasureSpec.getMode(heightMeasureSpec))
{
case MeasureSpec.AT_MOST:
if (newH < h)
h = newH;
break;
case MeasureSpec.EXACTLY:
break;
case MeasureSpec.UNSPECIFIED:
h = newH;
break;
}
setMeasuredDimension(w, h);
}
protected float coordFW(final int x, final int y)
{
return (float) x / y * width;
}
protected float coordFH(final int x, final int y)
{
return (float) x / y * height;
}
protected int coordW(final int x, final int y)
{
return Math.round((float) x / y * width);
}
protected int coordH(final int x, final int y)
{
return Math.round((float) x / y * height);
}
public TestView(final Context context, final AttributeSet attrs)
{
this(context, attrs, 0);
}
public TestView(final Context context)
{
this(context, null, 0);
}
public void setSpeedValue(final double speedValueRelative)
{
speedGauge.setValue(speedValueRelative);
}
public double setProgressValue(final double progressValue)
{
final double currentValue = progressGauge.value;
progressGauge.setValue(progressValue >= currentValue ? progressValue : currentValue);
return progressGauge.value;
}
public void setSignalValue(final double relativeSignal)
{
signalGauge.setValue(relativeSignal);
}
public void setHeaderString(final String headerString)
{
this.headerString = headerString;
//this.headerString = "TestTest_0TestTest_0TestTest_012";
}
public void setSubHeaderString(final String subHeaderString)
{
this.subHeaderString = subHeaderString;
}
public void setResultPingString(final String resultPingString)
{
this.resultPingString = resultPingString;
}
public void setResultDownString(final String resultDownString)
{
this.resultDownString = resultDownString;
}
public void setResultUpString(final String resultUpString)
{
this.resultUpString = resultUpString;
}
public void setProgressString(final String progressString)
{
this.progressString = progressString;
}
public void setSignalString(final String signalString)
{
this.signalString = signalString;
}
public void setSignalType(final int signalType)
{
this.signalType = signalType;
}
public void setTestStatus(final TestStatus testStatus)
{
this.testStatus = testStatus;
}
// @Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
// {
// get
// Log.d("TestView",
// getSuggestedMinimumWidth()+"/"+getSuggestedMinimumHeight());
// setMeasuredDimension(Math.round(width * scale), Math.round(height *
// scale));
// }
@Override
protected void onDraw(final Canvas canvas)
{
if (recycled)
return;
final int saveCount = canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
canvas.scale(scale, scale);
canvas.translate(internalPaddingLeft, internalPaddingTop);
canvas.drawBitmap(genBackgroundBitmap, 0, 0, bitmapPaint);
if (testStatus != null)
switch (testStatus)
{
case DOWN:
case INIT_UP:
canvas.drawBitmap(speedStatusDownBitmap, speedStatusDownX, speedStatusDownY, bitmapPaint);
break;
case UP:
case SPEEDTEST_END:
canvas.drawBitmap(speedStatusUpBitmap, speedStatusUpX, speedStatusUpY, bitmapPaint);
break;
}
final Bitmap signalRingBitmap;
switch (signalType)
{
case InformationCollector.SINGAL_TYPE_MOBILE:
signalRingBitmap = signalRingBitmapMobile;
break;
case InformationCollector.SINGAL_TYPE_WLAN:
signalRingBitmap = signalRingBitmapWlan;
break;
case InformationCollector.SINGAL_TYPE_RSRP:
signalRingBitmap = signalRingBitmapRsrp;
break;
default:
signalRingBitmap = null;
}
if (signalRingBitmap != null)
{
canvas.drawBitmap(signalRingBitmap, signalRingX, signalRingY, bitmapPaint);
canvas.drawBitmap(signalStatusBgBitmap, signalStatusBgX, signalStatusBgY, bitmapPaint);
canvas.drawText(signalDescriptionString, signalDescriptionX, signalDescriptionY, signalDescriptionPaint);
if (signalString != null)
canvas.drawText(signalString, signalX, signalY, signalPaint);
signalGauge.draw(canvas);
}
if (headerString != null)
canvas.drawText(headerString, headerX, headerY, headerPaint);
if (subHeaderString != null) {
headerPaint.setTextAlign(Align.RIGHT);
canvas.drawText(subHeaderString, subHeaderX, subHeaderY, headerPaint);
headerPaint.setTextAlign(Align.LEFT);
}
if (resultPingString != null)
canvas.drawText(resultPingString, resultPingX, resultPingY, resultPaint);
if (resultDownString != null)
canvas.drawText(resultDownString, resultDownX, resultDownY, resultPaint);
if (resultUpString != null)
canvas.drawText(resultUpString, resultUpX, resultUpY, resultPaint);
if (progressString != null)
canvas.drawText(progressString, progressX, progressY, progressPaint);
speedGauge.draw(canvas);
progressGauge.draw(canvas);
//canvas.drawBitmap(reflectionBitmap, reflectionX, reflectionY, bitmapPaint);
canvas.restoreToCount(saveCount);
}
public void recycle()
{
recycled = true;
genBackgroundBitmap.recycle();
//reflectionBitmap.recycle();
//resultBackgroundBitmap.recycle();
speedStatusDownBitmap.recycle();
speedStatusUpBitmap.recycle();
signalRingBitmapMobile.recycle();
signalRingBitmapWlan.recycle();
signalRingBitmapRsrp.recycle();
signalStatusBgBitmap.recycle();
speedGauge.recycle();
progressGauge.recycle();
signalGauge.recycle();
}
public String getHeaderString() {
return headerString;
}
public String getSubHeaderString() {
return subHeaderString;
}
public String getResultPingString() {
return resultPingString;
}
public String getResultDownString() {
return resultDownString;
}
public String getResultUpString() {
return resultUpString;
}
}