diff options
Diffstat (limited to 'src/cgeo/geocaching/cgCompassMini.java')
| -rw-r--r-- | src/cgeo/geocaching/cgCompassMini.java | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/cgeo/geocaching/cgCompassMini.java b/src/cgeo/geocaching/cgCompassMini.java new file mode 100644 index 0000000..cc815bf --- /dev/null +++ b/src/cgeo/geocaching/cgCompassMini.java @@ -0,0 +1,176 @@ +package cgeo.geocaching; + +import android.util.AttributeSet; +import android.view.View; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.graphics.Canvas; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +public class cgCompassMini extends View { + private int arrowSkin = R.drawable.compass_arrow_mini_white; + private Boolean lock = false; + private Context context = null; + private cgBase base = null; + private Double cacheLat = null; + private Double cacheLon = null; + private Bitmap compassArrow = null; + private Double azimuth = new Double(0); + private Double heading = new Double(0); + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + + public cgCompassMini(Context contextIn) { + super(contextIn); + context = contextIn; + } + + public cgCompassMini(Context contextIn, AttributeSet attrs) { + super(contextIn, attrs); + context = contextIn; + + TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.cgCompassMini); + int usedSkin = attributes.getInt(R.styleable.cgCompassMini_skin, 0); + if (usedSkin == 1) arrowSkin = R.drawable.compass_arrow_mini_black; + else arrowSkin = R.drawable.compass_arrow_mini_white; + } + + @Override + public void onAttachedToWindow() { + compassArrow = BitmapFactory.decodeResource(context.getResources(), arrowSkin); + + setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + } + + @Override + public void onDetachedFromWindow() { + if (compassArrow != null) { + compassArrow.recycle(); + compassArrow = null; + } + } + + public void setContent(cgBase baseIn, Double cacheLatIn, Double cacheLonIn) { + base = baseIn; + cacheLat = cacheLatIn; + cacheLon = cacheLonIn; + } + + protected void updateAzimuth(Double azimuthIn) { + azimuth = azimuthIn; + + updateDirection(); + } + + protected void updateHeading(Double headingIn) { + heading = headingIn; + + updateDirection(); + } + + protected void updateCoords(Double latitudeIn, Double longitudeIn) { + if (latitudeIn == null || longitudeIn == null || cacheLat == null || cacheLon == null) { + return; + } + + heading = cgBase.getHeading(latitudeIn, longitudeIn, cacheLat, cacheLon); + + updateDirection(); + } + + protected void updateDirection() { + if (compassArrow == null || compassArrow.isRecycled() == true) { + return; + } + + // compass margins + int compassRoseWidth = compassArrow.getWidth(); + int compassRoseHeight = compassArrow.getWidth(); + int marginLeft = (getWidth() - compassRoseWidth) / 2; + int marginTop = (getHeight() - compassRoseHeight) / 2; + + invalidate(marginLeft, marginTop, (marginLeft + compassRoseWidth), (marginTop + compassRoseHeight)); + } + + @Override + protected void onDraw(Canvas canvas){ + lock = true; + + super.onDraw(canvas); + + Double azimuthRelative = azimuth - heading; + if (azimuthRelative < 0) { + azimuthRelative = azimuthRelative + 360; + } else if (azimuthRelative >= 360) { + azimuthRelative = azimuthRelative - 360; + } + + // compass margins + canvas.setDrawFilter(setfil); + + int marginLeft = 0; + int marginTop = 0; + + int compassArrowWidth = compassArrow.getWidth(); + int compassArrowHeight = compassArrow.getWidth(); + + int canvasCenterX = (compassArrowWidth / 2) + ((getWidth() - compassArrowWidth) / 2); + int canvasCenterY = (compassArrowHeight / 2) + ((getHeight() - compassArrowHeight) / 2); + + marginLeft = (getWidth() - compassArrowWidth) / 2; + marginTop = (getHeight() - compassArrowHeight) / 2; + + canvas.rotate(new Float(-(azimuthRelative)), canvasCenterX, canvasCenterY); + canvas.drawBitmap(compassArrow, marginLeft, marginTop, null); + canvas.rotate(new Float(azimuthRelative), canvasCenterX, canvasCenterY); + + canvas.setDrawFilter(remfil); + + lock = false; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); + } + + private int measureWidth(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } else { + result = 21 + getPaddingLeft() + getPaddingRight(); + + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } + + return result; + } + + private int measureHeight(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } else { + result = 21 + getPaddingTop() + getPaddingBottom(); + + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } + + return result; + } +}
\ No newline at end of file |
