Gauge.java :  » UnTagged » evdash » autorad » android » widget » gauge » Android Open Source

Android Open Source » UnTagged » evdash 
evdash » autorad » android » widget » gauge » Gauge.java
package autorad.android.widget.gauge;


import java.util.LinkedList;
import java.util.Queue;

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.view.animation.Animation.AnimationListener;

import android.widget.ImageView;

import autorad.android.C;
import autorad.android.DashDisplay;
import autorad.android.R;

import autorad.android.sensor.DataType;


public class Gauge extends AbstractGauge implements AnimationListener {


  ImageView needle;
  ImageView face;

  int endAngle;
  int startAngle;
  int restAngle;
  int minDataValue;
  int maxDataValue;
  int maxNeedleSweepDistance;
  
  float lastData = -1f;
  float lastPos = 0f;
  boolean animating = false;
  
  
  Queue<RotateAnimation> animationQueue = new LinkedList<RotateAnimation>();
  
  Animation currentAnimation;
  
  
  public Gauge(DashDisplay ctx, GaugeSettings gaugeSettings) {
    super(ctx);
    this.ctx = ctx;
    this.gaugeSettings = gaugeSettings;
    this.gaugeType = gaugeSettings.getGaugeType();
    this.details = gaugeType.getGaugeDetails();
    this.dataTypes = details.getDataTypes();
    
    this.maxNeedleSweepDistance = details.getEndAngle() - details.getRestAngle();
    this.minDataValue = details.getMinDataValue();
    this.maxDataValue = details.getMaxDataValue();
    this.startAngle = details.getStartAngle();
    this.endAngle = details.getEndAngle();
    this.restAngle = details.getRestAngle();

    this.setTag(gaugeSettings);
    
    face = new ImageView(ctx);
    needle = new ImageView(ctx);
    
    // System.gc();
    
    switch (gaugeType) {
    
    case RPM:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.rpm400));
      initNeedle(R.drawable.needle400);
      
      break;
      
    case PACK_VOLTAGE:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.batteryvolt200));
      initNeedle(R.drawable.needlevolt200);
      
      break;
      
    case CONTROLLER_TEMPERATURE:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.temp200));
      initNeedle(R.drawable.needlevolt200);
      
      break;
      
    case BATTERY_CURRENT_LOW:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.amps400));
      initNeedle(R.drawable.needle400);
      break;
      
    case BATTERY_CURRENT_HIGH:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.highamps400));
      initNeedle(R.drawable.needle400);
      
      break;
    
    case SPEED_KPH:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.kmph400));
      initNeedle(R.drawable.needle400);
      
      break;
    case SPEED_MPH:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.mph400));
      initNeedle(R.drawable.needle400);
      
      break;
    case SPEED_OLDSKOOL_MPH:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.minispeed400));
      initNeedle(R.drawable.minispeedneedle400);
      
      break;
      
    case LATERAL_G:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.lateralg200));
      initNeedle(R.drawable.needlevolt200);
      
      break;
    
    case ACCELERATION_G:
      face.setImageDrawable(ctx.getResources().getDrawable(R.drawable.accelerationg200));
      initNeedle(R.drawable.needlevolt200);
      
      break;
    }

    
    face.setLongClickable(true);
    //face.setOnLongClickListener(new OnLongClickListener() {
        //    public boolean onLongClick(View v) {
                
        //        return false;
        //    }
    //});
    
    face.setOnTouchListener(new OnTouchListener() {
      public boolean onTouch(View arg0, MotionEvent event) {
        onGaugeMotionEvent(event);
        return false;
      }
    });
    
    applySettings();
    
    this.addView(face);
    this.addView(needle);
    
    rotateNeedle(details.getRestAngle(), 0);
  }
  
  public void cleanup() {
    
    ctx = null;
    currentAnimation = null;
    animationQueue.clear();
    animationQueue = null;
    face.setOnTouchListener(null);
    face.setImageDrawable(null);
    needle.setImageDrawable(null);
    needle = null;
    face = null;
    gaugeType = null;
    dataTypes = null;
    gaugeSettings= null;
    details = null;
    
    
  }
  
  public String getToastString() {
    if (lastData == -1) {
      return null;
    } else {
      return lastData + " " + details.getUnits();
    }
  }
  
  
  
  public void applySettings() {
    switch (gaugeSettings.getSize()) {
    case TINY:
      size = 100;
      break;
    case VERY_SMALL:
      size = 150;
      break;
    case SMALL:
      size = 200;
      break;
    case MEDIUM:
      size = 300;
      break;
    case LARGE:
      size = 400;
      break;
    }

    LayoutParams params = new LayoutParams(size, size);
    params.setMargins(0, 0, 0, 0);
    face.setLayoutParams(params);
    needle.setLayoutParams(params);
    rotateNeedle(1, 1);
  }

  public void initNeedle(int drawableId) {
    
    //Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
    //needle.setImageDrawable(new BitmapDrawable(bitmap));

    needle.setImageDrawable(ctx.getResources().getDrawable(drawableId));  
    
    //LayoutParams params = new LayoutParams(size, size);
    //params.setMargins(0, 0, 0, 0);
    //needle.setLayoutParams(params);
    
    
  }
  
  public void fullSweepReset() {
    if (C.D) Log.d(C.TAG, "Full sweep reset requested");
    int angleRotation = details.getEndAngle() - (int)lastPos;
    //int angleBackRotation = details.getEndAngle() - details.getRestAngle();
    
    rotateNeedle(angleRotation, 1000);
    rotateNeedleToPoint(restAngle, 1500);
    lastData = 0;
  }
  
  public void calibrate() {
    int increment;
    switch (gaugeType) {
    case RPM:
      increment = 8;
      break;
    case BATTERY_CURRENT_LOW: case SPEED_KPH:
      increment = 9;
      break;
    default:
      increment = 10;
    }
    
    int incrementValue = (maxDataValue - minDataValue)/increment;
    for (int i = 0; i<increment; ) {
      float d1 = ((float)(incrementValue*++i))/maxDataValue;
      float angle = startAngle + (d1 * (maxNeedleSweepDistance));
      if (C.D) Log.d(C.TAG, "Calibrate: Data=" + (incrementValue*i) + " angle=" + angle);
      rotateNeedleToPoint(angle,1000);
    }
    rotateNeedleToPoint(restAngle,1500);
    
  }
  
    private boolean rotateNeedle(int degrees, int duration) {

      if (C.D) Log.d(C.TAG, "Rotating=" + degrees + " lastPos=" + lastPos + " duration =  " + duration);
      float nextPos = lastPos+degrees;
        RotateAnimation d = new RotateAnimation(lastPos, nextPos, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
        d.setDuration(duration);
        d.setAnimationListener(this);
        d.setFillAfter(true);
        
        lastPos = nextPos;
        
        if (currentAnimation == null) {
          //animating = true;
          //needle.startAnimation(d);
          currentAnimation = d;
          runCurrentAnimationOnUiThread();
        } else {
          if (C.D) Log.d("EVDASH", "queued animation");
          animationQueue.add(d);
        }
        
        return true;
    }

    private boolean rotateNeedleToPoint(float toDegrees, int duration) {

      // Work out a duration for this animation
      float distance = toDegrees - lastPos;
      if (duration == 0) {
        duration = (int)(2000 * distance/maxNeedleSweepDistance);
      }
      if (duration < 0) {
        duration *= -1;
      }
      
      if (C.D) Log.d(C.TAG, "Rotating To=" + toDegrees + " lastPos=" + lastPos + "duration =  " + duration);
        RotateAnimation d = new RotateAnimation(lastPos, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
        d.setDuration(duration);
        d.setAnimationListener(this);
        d.setFillAfter(true);
        
        lastPos = toDegrees;
        
        if (currentAnimation == null) {
          //animating = true;
          //needle.startAnimation(d);
          currentAnimation = d;
          runCurrentAnimationOnUiThread();
        } else {
          if (C.D) Log.d(C.TAG, "queued animation");
          animationQueue.add(d);
        }
        
        return true;
    }

    
  public void onAnimationEnd(Animation arg0) {  
    //animating = false;
    if (!animationQueue.isEmpty()) {
      currentAnimation = animationQueue.remove();
      runCurrentAnimationOnUiThread();
      //ctx.getHandler().post(new Runnable() {
      //  public void run() {
      //    needle.startAnimation(animationQueue.remove());
      //  }
      //});
    } else {
      currentAnimation = null;
    }
  }
  
  private void runCurrentAnimationOnUiThread() {
    ctx.getHandler().post(new Runnable() {
      public void run() {
        if (currentAnimation != null) {
          needle.startAnimation(currentAnimation);
        }
      }
    });
  }

  public void onAnimationRepeat(Animation arg0) {  
  }

  public void onAnimationStart(Animation arg0) {
    animating = true;
  }
  
  public void onData(DataType type, float... data) {
    //if (C.D) Log.d("EVDASH", "Gauge Received Data:" + data);
    float d = data[0];
    if (lastData == d) return;
    
    
    if (d < minDataValue) {
      if (C.D) Log.d(C.TAG, "Gauge Data Below Minimum");
      rotateNeedleToPoint(startAngle,0);  
    } else if (d > maxDataValue) {
      if (C.D) Log.d(C.TAG, "Gauge Data Above Maximum ");
      return;
      //rotateNeedleToPoint(endAngle,0);
    } else {
      
      float d1 = d/maxDataValue;
      if (C.D) Log.d(C.TAG, "data=" + data + " maxDataV=" + maxDataValue + " d/md=" + d1 );
      
      float angle = restAngle + (d1 * (maxNeedleSweepDistance));
      
      if (C.D) Log.d(C.TAG, "Gauge rotate to angle " + angle);
      rotateNeedleToPoint(angle,0); 
    }
    lastData = d;
    
  }
  

  protected void onGaugeMotionEvent(MotionEvent event) {
    ctx.onGaugeMotionEvent(this, event);
  }

  


  
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.