aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching/cgCompass.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgeo/geocaching/cgCompass.java')
-rw-r--r--src/cgeo/geocaching/cgCompass.java503
1 files changed, 253 insertions, 250 deletions
diff --git a/src/cgeo/geocaching/cgCompass.java b/src/cgeo/geocaching/cgCompass.java
index f45501d..e748bef 100644
--- a/src/cgeo/geocaching/cgCompass.java
+++ b/src/cgeo/geocaching/cgCompass.java
@@ -14,255 +14,258 @@ import android.view.View;
public class cgCompass extends View {
- private changeThread watchdog = null;
- private volatile boolean wantStop = false;
- private Context context = null;
- private Bitmap compassUnderlay = null;
- private Bitmap compassRose = null;
- private Bitmap compassArrow = null;
- private Bitmap compassOverlay = null;
- private double azimuth = 0.0;
- private double heading = 0.0;
- private double cacheHeading = 0.0;
- private double northHeading = 0.0;
- private PaintFlagsDrawFilter setfil = null;
- private PaintFlagsDrawFilter remfil = null;
- private int compassUnderlayWidth = 0;
- private int compassUnderlayHeight = 0;
- private int compassRoseWidth = 0;
- private int compassRoseHeight = 0;
- private int compassArrowWidth = 0;
- private int compassArrowHeight = 0;
- private int compassOverlayWidth = 0;
- private int compassOverlayHeight = 0;
- private boolean initialDisplay;
- private Handler changeHandler = new Handler() {
-
- @Override
- public void handleMessage(Message message) {
- try {
- invalidate();
- } catch (Exception e) {
- Log.e(cgSettings.tag, "cgCompass.changeHandler: " + e.toString());
- }
- }
- };
-
- public cgCompass(Context contextIn) {
- super(contextIn);
- context = contextIn;
- }
-
- public cgCompass(Context contextIn, AttributeSet attrs) {
- super(contextIn, attrs);
- context = contextIn;
- }
-
- @Override
- public void onAttachedToWindow() {
- compassUnderlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_underlay);
- compassRose = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_rose);
- compassArrow = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_arrow);
- compassOverlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_overlay);
-
- compassUnderlayWidth = compassUnderlay.getWidth();
- compassUnderlayHeight = compassUnderlay.getWidth();
- compassRoseWidth = compassRose.getWidth();
- compassRoseHeight = compassRose.getWidth();
- compassArrowWidth = compassArrow.getWidth();
- compassArrowHeight = compassArrow.getWidth();
- compassOverlayWidth = compassOverlay.getWidth();
- compassOverlayHeight = compassOverlay.getWidth();
-
- setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
- remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
-
- initialDisplay = true;
- wantStop = false;
-
- watchdog = new changeThread();
- watchdog.start();
- }
-
- @Override
- public void onDetachedFromWindow() {
- wantStop = true;
-
- if (compassUnderlay != null) {
- compassUnderlay.recycle();
- }
-
- if (compassRose != null) {
- compassRose.recycle();
- }
-
- if (compassArrow != null) {
- compassArrow.recycle();
- }
-
- if (compassOverlay != null) {
- compassOverlay.recycle();
- }
- }
-
- protected synchronized void updateNorth(double northHeadingIn, double cacheHeadingIn) {
- if (initialDisplay) {
- // We will force the compass to move brutally if this is the first
- // update since it is visible.
- azimuth = northHeadingIn;
- heading = cacheHeadingIn;
- initialDisplay = false;
- }
- northHeading = northHeadingIn;
- cacheHeading = cacheHeadingIn;
- }
-
- /**
- * Compute the new value, moving by small increments.
- * @param goal the goal to reach
- * @param actual the actual value
- * @return the new value
- */
- static protected double smoothUpdate(double goal, double actual) {
- double diff = goal - actual;
- final boolean largeDiff = Math.abs(diff) > 5;
-
- double offset = 0.0;
-
- if (diff < 0.0) {
- diff = diff + 360.0;
- } else if (diff >= 360.0) {
- diff = diff - 360.0;
- }
-
- // If the difference is smaller than 1 degree, do nothing as it
- // causes the arrow to vibrate.
- if (diff > 1.0 && diff <= 180.0) {
- offset = largeDiff ? 2.0 : 1.0;
- } else if (diff > 180.0 && diff < 359.0) {
- offset = largeDiff ? -2.0 : -1.0;
- }
-
- return actual + offset;
- }
-
- private class changeThread extends Thread {
-
- @Override
- public void run() {
- while (wantStop == false) {
- try {
- sleep(50);
- } catch (Exception e) {
- // nothing
- }
-
- synchronized(cgCompass.this) {
- azimuth = smoothUpdate(northHeading, azimuth);
- heading = smoothUpdate(cacheHeading, heading);
- }
-
- changeHandler.sendMessage(new Message());
- }
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- double currentAzimuth;
- double currentHeading;
-
- synchronized(this) {
- currentAzimuth = azimuth;
- currentHeading = heading;
- }
-
- double azimuthTemp = currentAzimuth;
- double azimuthRelative = azimuthTemp - currentHeading;
- if (azimuthRelative < 0) {
- azimuthRelative = azimuthRelative + 360;
- } else if (azimuthRelative >= 360) {
- azimuthRelative = azimuthRelative - 360;
- }
-
- // compass margins
- int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2);
- int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2);
-
- int marginLeftTemp = 0;
- int marginTopTemp = 0;
-
- super.onDraw(canvas);
-
- canvas.save();
- canvas.setDrawFilter(setfil);
-
- marginLeftTemp = (getWidth() - compassUnderlayWidth) / 2;
- marginTopTemp = (getHeight() - compassUnderlayHeight) / 2;
-
- canvas.drawBitmap(compassUnderlay, marginLeftTemp, marginTopTemp, null);
-
- marginLeftTemp = (getWidth() - compassRoseWidth) / 2;
- marginTopTemp = (getHeight() - compassRoseHeight) / 2;
-
- canvas.rotate((float) -azimuthTemp, canvasCenterX, canvasCenterY);
- canvas.drawBitmap(compassRose, marginLeftTemp, marginTopTemp, null);
- canvas.rotate((float) azimuthTemp, canvasCenterX, canvasCenterY);
-
- marginLeftTemp = (getWidth() - compassArrowWidth) / 2;
- marginTopTemp = (getHeight() - compassArrowHeight) / 2;
-
- canvas.rotate((float) -azimuthRelative, canvasCenterX, canvasCenterY);
- canvas.drawBitmap(compassArrow, marginLeftTemp, marginTopTemp, null);
- canvas.rotate((float) azimuthRelative, canvasCenterX, canvasCenterY);
-
- marginLeftTemp = (getWidth() - compassOverlayWidth) / 2;
- marginTopTemp = (getHeight() - compassOverlayHeight) / 2;
-
- canvas.drawBitmap(compassOverlay, marginLeftTemp, marginTopTemp, null);
-
- canvas.setDrawFilter(remfil);
- canvas.restore();
- }
-
- @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 = compassArrow.getWidth() + 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 = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom();
-
- if (specMode == MeasureSpec.AT_MOST) {
- result = Math.min(result, specSize);
- }
- }
+ private changeThread watchdog = null;
+ private volatile boolean wantStop = false;
+ private Context context = null;
+ private Bitmap compassUnderlay = null;
+ private Bitmap compassRose = null;
+ private Bitmap compassArrow = null;
+ private Bitmap compassOverlay = null;
+ private double azimuth = 0.0;
+ private double heading = 0.0;
+ private double cacheHeading = 0.0;
+ private double northHeading = 0.0;
+ private PaintFlagsDrawFilter setfil = null;
+ private PaintFlagsDrawFilter remfil = null;
+ private int compassUnderlayWidth = 0;
+ private int compassUnderlayHeight = 0;
+ private int compassRoseWidth = 0;
+ private int compassRoseHeight = 0;
+ private int compassArrowWidth = 0;
+ private int compassArrowHeight = 0;
+ private int compassOverlayWidth = 0;
+ private int compassOverlayHeight = 0;
+ private boolean initialDisplay;
+ private Handler changeHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message message) {
+ try {
+ invalidate();
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgCompass.changeHandler: " + e.toString());
+ }
+ }
+ };
+
+ public cgCompass(Context contextIn) {
+ super(contextIn);
+ context = contextIn;
+ }
+
+ public cgCompass(Context contextIn, AttributeSet attrs) {
+ super(contextIn, attrs);
+ context = contextIn;
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ compassUnderlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_underlay);
+ compassRose = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_rose);
+ compassArrow = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_arrow);
+ compassOverlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_overlay);
+
+ compassUnderlayWidth = compassUnderlay.getWidth();
+ compassUnderlayHeight = compassUnderlay.getWidth();
+ compassRoseWidth = compassRose.getWidth();
+ compassRoseHeight = compassRose.getWidth();
+ compassArrowWidth = compassArrow.getWidth();
+ compassArrowHeight = compassArrow.getWidth();
+ compassOverlayWidth = compassOverlay.getWidth();
+ compassOverlayHeight = compassOverlay.getWidth();
+
+ setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
+ remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
+
+ initialDisplay = true;
+ wantStop = false;
+
+ watchdog = new changeThread();
+ watchdog.start();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ wantStop = true;
+
+ if (compassUnderlay != null) {
+ compassUnderlay.recycle();
+ }
+
+ if (compassRose != null) {
+ compassRose.recycle();
+ }
+
+ if (compassArrow != null) {
+ compassArrow.recycle();
+ }
+
+ if (compassOverlay != null) {
+ compassOverlay.recycle();
+ }
+ }
+
+ protected synchronized void updateNorth(double northHeadingIn, double cacheHeadingIn) {
+ if (initialDisplay) {
+ // We will force the compass to move brutally if this is the first
+ // update since it is visible.
+ azimuth = northHeadingIn;
+ heading = cacheHeadingIn;
+ initialDisplay = false;
+ }
+ northHeading = northHeadingIn;
+ cacheHeading = cacheHeadingIn;
+ }
+
+ /**
+ * Compute the new value, moving by small increments.
+ *
+ * @param goal
+ * the goal to reach
+ * @param actual
+ * the actual value
+ * @return the new value
+ */
+ static protected double smoothUpdate(double goal, double actual) {
+ double diff = goal - actual;
+ final boolean largeDiff = Math.abs(diff) > 5;
+
+ double offset = 0.0;
+
+ if (diff < 0.0) {
+ diff = diff + 360.0;
+ } else if (diff >= 360.0) {
+ diff = diff - 360.0;
+ }
+
+ // If the difference is smaller than 1 degree, do nothing as it
+ // causes the arrow to vibrate.
+ if (diff > 1.0 && diff <= 180.0) {
+ offset = largeDiff ? 2.0 : 1.0;
+ } else if (diff > 180.0 && diff < 359.0) {
+ offset = largeDiff ? -2.0 : -1.0;
+ }
+
+ return actual + offset;
+ }
+
+ private class changeThread extends Thread {
+
+ @Override
+ public void run() {
+ while (wantStop == false) {
+ try {
+ sleep(50);
+ } catch (Exception e) {
+ // nothing
+ }
+
+ synchronized (cgCompass.this) {
+ azimuth = smoothUpdate(northHeading, azimuth);
+ heading = smoothUpdate(cacheHeading, heading);
+ }
+
+ changeHandler.sendMessage(new Message());
+ }
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ double currentAzimuth;
+ double currentHeading;
+
+ synchronized (this) {
+ currentAzimuth = azimuth;
+ currentHeading = heading;
+ }
+
+ double azimuthTemp = currentAzimuth;
+ double azimuthRelative = azimuthTemp - currentHeading;
+ if (azimuthRelative < 0) {
+ azimuthRelative = azimuthRelative + 360;
+ } else if (azimuthRelative >= 360) {
+ azimuthRelative = azimuthRelative - 360;
+ }
+
+ // compass margins
+ int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2);
+ int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2);
+
+ int marginLeftTemp = 0;
+ int marginTopTemp = 0;
+
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.setDrawFilter(setfil);
+
+ marginLeftTemp = (getWidth() - compassUnderlayWidth) / 2;
+ marginTopTemp = (getHeight() - compassUnderlayHeight) / 2;
+
+ canvas.drawBitmap(compassUnderlay, marginLeftTemp, marginTopTemp, null);
+
+ marginLeftTemp = (getWidth() - compassRoseWidth) / 2;
+ marginTopTemp = (getHeight() - compassRoseHeight) / 2;
+
+ canvas.rotate((float) -azimuthTemp, canvasCenterX, canvasCenterY);
+ canvas.drawBitmap(compassRose, marginLeftTemp, marginTopTemp, null);
+ canvas.rotate((float) azimuthTemp, canvasCenterX, canvasCenterY);
+
+ marginLeftTemp = (getWidth() - compassArrowWidth) / 2;
+ marginTopTemp = (getHeight() - compassArrowHeight) / 2;
+
+ canvas.rotate((float) -azimuthRelative, canvasCenterX, canvasCenterY);
+ canvas.drawBitmap(compassArrow, marginLeftTemp, marginTopTemp, null);
+ canvas.rotate((float) azimuthRelative, canvasCenterX, canvasCenterY);
+
+ marginLeftTemp = (getWidth() - compassOverlayWidth) / 2;
+ marginTopTemp = (getHeight() - compassOverlayHeight) / 2;
+
+ canvas.drawBitmap(compassOverlay, marginLeftTemp, marginTopTemp, null);
+
+ canvas.setDrawFilter(remfil);
+ canvas.restore();
+ }
+
+ @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 = compassArrow.getWidth() + 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 = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom();
+
+ if (specMode == MeasureSpec.AT_MOST) {
+ result = Math.min(result, specSize);
+ }
+ }
- return result;
- }
+ return result;
+ }
} \ No newline at end of file