diff options
author | Bananeweizen <bananeweizen@gmx.de> | 2012-01-14 15:02:15 +0100 |
---|---|---|
committer | Bananeweizen <bananeweizen@gmx.de> | 2012-01-14 15:02:15 +0100 |
commit | e61a40fc8a4a3d5ab5a59346eddd1c43bcc4857e (patch) | |
tree | a2a8aec422fde537c500cf90ad70e606ba416121 /main/src/cgeo/geocaching/ui/CompassMiniView.java | |
parent | 77a8bc851569ae7a82f76a0913b39006074ac56a (diff) | |
download | cgeo-e61a40fc8a4a3d5ab5a59346eddd1c43bcc4857e.zip cgeo-e61a40fc8a4a3d5ab5a59346eddd1c43bcc4857e.tar.gz cgeo-e61a40fc8a4a3d5ab5a59346eddd1c43bcc4857e.tar.bz2 |
refactoring: move more widget related classes into own package
Diffstat (limited to 'main/src/cgeo/geocaching/ui/CompassMiniView.java')
-rw-r--r-- | main/src/cgeo/geocaching/ui/CompassMiniView.java | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/ui/CompassMiniView.java b/main/src/cgeo/geocaching/ui/CompassMiniView.java new file mode 100644 index 0000000..5f3b8c2 --- /dev/null +++ b/main/src/cgeo/geocaching/ui/CompassMiniView.java @@ -0,0 +1,175 @@ +package cgeo.geocaching.ui; + +import cgeo.geocaching.R; +import cgeo.geocaching.R.drawable; +import cgeo.geocaching.R.styleable; +import cgeo.geocaching.geopoint.Geopoint; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.util.AttributeSet; +import android.view.View; + +public class CompassMiniView extends View { + private int arrowSkin = R.drawable.compass_arrow_mini_white; + private Context context = null; + private Geopoint cacheCoords = null; + private Bitmap compassArrow = null; + private float azimuth = 0; + private float heading = 0; + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + + public CompassMiniView(Context contextIn) { + super(contextIn); + context = contextIn; + } + + public CompassMiniView(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(final Geopoint cacheCoordsIn) { + cacheCoords = cacheCoordsIn; + } + + protected void updateAzimuth(float azimuthIn) { + azimuth = azimuthIn; + + updateDirection(); + } + + protected void updateHeading(float headingIn) { + heading = headingIn; + + updateDirection(); + } + + protected void updateCoords(final Geopoint coordsIn) { + if (coordsIn == null || cacheCoords == null) { + return; + } + + heading = coordsIn.bearingTo(cacheCoords); + + updateDirection(); + } + + protected void updateDirection() { + if (compassArrow == null || compassArrow.isRecycled()) { + 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) { + super.onDraw(canvas); + + float azimuthRelative = azimuth - heading; + if (azimuthRelative < 0) { + azimuthRelative += 360; + } else if (azimuthRelative >= 360) { + 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(-azimuthRelative, canvasCenterX, canvasCenterY); + canvas.drawBitmap(compassArrow, marginLeft, marginTop, null); + canvas.rotate(azimuthRelative, canvasCenterX, canvasCenterY); + + canvas.setDrawFilter(remfil); + } + + @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 |