/*
CanZE
Take a closer look at your ZE car
Copyright (C) 2015 - The CanZE Team
http://canze.fisch.lu
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 3 of the License, or 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, see <http://www.gnu.org/licenses/>.
*/
package lu.fisch.canze.widgets;
import android.graphics.Point;
import com.google.gson.Gson;
import lu.fisch.awt.Color;
import lu.fisch.awt.Graphics;
import lu.fisch.awt.Polygon;
import lu.fisch.canze.interfaces.DrawSurfaceInterface;
/**
*
* @author robertfisch
*/
public class Tacho extends Drawable {
protected double angle = 240;
protected boolean autoRange = false;
protected int padding = 5;
public Tacho() {
super();
}
public Tacho(DrawSurfaceInterface drawSurface, int x, int y, int width, int height) {
this.drawSurface=drawSurface;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Tacho(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void draw(Graphics g)
{
// clean the surface
g.setColor(Color.WHITE);
g.fillRect(0,0,getWidth(),getHeight());
g.setTextSize(12);
double alpha = (360-angle)/2.;
// determine the rayon to be used
double rayon = 0;
if(angle>=180)
rayon = Math.min(width/2.,height/(1+Math.sin(mkRad(90-alpha))))-padding;
else
rayon = Math.min((width/2)/Math.cos(mkRad(90-angle/2)),height)-padding;
// determine center point
Point center = new Point(x+(width/2),y+(int)(rayon+padding));
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
// draw the frame
g.setColor(Color.GRAY_DARK);
double ax,ay,bx=0,by=0;
// draw right arm
ax = center.x+rayon*Math.cos(mkRad(-90+alpha));
ay = center.y-rayon*Math.sin(mkRad(-90+alpha));
//g.drawLine(center.x,center.y,(int)ax,(int)ay);
// draw arc
for(double i=-90+alpha; i<=360-90-alpha; i+=2)
{
bx = center.x+rayon*Math.cos(mkRad(i));
by = center.y-rayon*Math.sin(mkRad(i));
g.drawLine((int)ax, (int)ay, (int)bx, (int)by);
ax=bx;
ay=by;
}
// draw left arm
ax = center.x+rayon*Math.cos(mkRad(-90-alpha));
ay = center.y-rayon*Math.sin(mkRad(-90-alpha));
//g.drawLine(center.x,center.y,(int)ax,(int)ay);
// draw last chunk of arc
g.drawLine((int)ax, (int)ay, (int)bx, (int)by);
// draw the labels
g.setColor(Color.BLACK);
double dist = 360-2*alpha;
int actual = min;
// draw the minor ticks
if(minorTicks >0 || majorTicks>0) {
g.setColor(Color.GRAY_DARK);
int toTicks = minorTicks;
if (toTicks == 0) toTicks = majorTicks;
double accel = dist / ((max - min) / toTicks);
int sum = 0;
for (double i = 360 - 90 - alpha; i > (int)( -90 + alpha)-accel; i -= accel) {
if (minorTicks > 0) {
ax = center.x + (rayon) * Math.cos(mkRad(i));
ay = center.y - (rayon) * Math.sin(mkRad(i));
bx = center.x + (rayon - 6) * Math.cos(mkRad(i));
by = center.y - (rayon - 6) * Math.sin(mkRad(i));
g.drawLine((int) ax, (int) ay, (int) bx, (int) by);
}
// draw majorTicks
if (majorTicks != 0 && sum % majorTicks == 0) {
if (majorTicks > 0) {
ax = center.x + (rayon) * Math.cos(mkRad(i));
ay = center.y - (rayon) * Math.sin(mkRad(i));
bx = center.x + (rayon - 12) * Math.cos(mkRad(i));
by = center.y - (rayon - 12) * Math.sin(mkRad(i));
g.drawLine((int) ax, (int) ay, (int) bx, (int) by);
}
// draw String
if (showLabels) {
bx = center.x + (rayon - 24) * Math.cos(mkRad(i));
by = center.y - (rayon - 24) * Math.sin(mkRad(i));
String text = (actual) + "";
double sw = g.stringWidth(text);
g.drawString(text, (int) (bx - (sw/2. + sw/2.*Math.cos(mkRad(i))) ), (int) (by + g.stringHeight(text) / 2));
}
actual += majorTicks;
}
sum += minorTicks;
}
}
// draw the needle
g.setColor(Color.RED);
double rota = 90+alpha+dist*(value-min)/(max-min);
Polygon p = new Polygon();
double needleLength = rayon-45;
double pointerLength = rayon*0.1;
double angleDiff = 5;
p.addPoint(center.x,
center.y);
p.addPoint((int)(center.x+(needleLength-pointerLength)*Math.cos(mkRad(rota + angleDiff))),
(int)(center.y+(needleLength-pointerLength)*Math.sin(mkRad(rota + angleDiff))));
p.addPoint((int)(center.x+needleLength*Math.cos(mkRad(rota))),
(int)(center.y+needleLength*Math.sin(mkRad(rota))));
p.addPoint((int)(center.x+(needleLength-pointerLength)*Math.cos(mkRad(rota-angleDiff))),
(int)(center.y+(needleLength-pointerLength)*Math.sin(mkRad(rota - angleDiff))));
g.fillPolygon(p);
// draw the value
if(showValue)
{
if(field !=null) {
g.setTextSize(Math.min(width / 7, 40));
String text = String.format("%." + String.valueOf(field.getDecimals()) + "f", field.getValue());
int tw = g.stringWidth(text);
int th = g.stringHeight(text);
int tx = center.x-tw/2-3;
int ty = center.y+th;
g.setColor(Color.WHITE);
g.fillRect(tx - 1, ty - th, tw + 7, th + 5);
//g.setColor(Color.BLACK);
//g.drawRect(tx - 1, ty - th, tw + 7, th +5);
g.setColor(Color.GREEN_DARK);
g.drawString(text, tx, ty);
}
}
// draw the title
if(title!=null && !title.equals(""))
{
g.setColor(Color.BLUE);
g.setTextSize(20);
int tw = g.stringWidth(title);
//int th = g.stringHeight(title);
int tx = getX()+getWidth()/2-tw/2;
int ty = getY()+getHeight()-8;
g.drawString(title,tx,ty);
}
}
/* --------------------------------
* Getters & setters
\ ------------------------------ */
public void setAngle(double angle) {
this.angle = angle;
}
public void setValue(int value) {
if(autoRange)
{
if(value<min) min=value;
else if(value>max) max=value;
}
else
{
if(value<min) value=min;
else if(value>max) value=max;
}
this.value = value;
}
/* --------------------------------
* Serialization
\ ------------------------------ */
@Override
public String dataToJson() {
return "";
}
@Override
public void dataFromJson(String json) {
}
}