package org.r3pek.pharmacies.widgets; import org.r3pek.pharmacies.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Display; import android.view.View; import android.view.WindowManager; public class Compass extends View implements ImageOrientationSensor { /* Orientation * 0 -> portrait * 1 -> landscape * 2 -> inverted portrait * 3 -> inverted landscape */ private final int orientationCompensation[] = {0, 90, 180, 270}; private Context ctx; private float bearing; private float orientation; private Drawable needleBackgound; private Drawable needle; public Compass(Context context) { super(context); ctx = context; setDrawable(); } public Compass(Context context, AttributeSet attrs) { super(context, attrs); ctx = context; setDrawable(); } public Compass(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); ctx = context; setDrawable(); } private void setDrawable() { needleBackgound = ctx.getResources().getDrawable(R.drawable.compass_background); needle = ctx.getResources().getDrawable(R.drawable.compass_needle); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Display display = ((WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); float rotation = bearing - orientation - orientationCompensation[display.getOrientation()] - 45; float keyPoints[] = {-4, 4, 4, -4}; Matrix matrix = new Matrix(); matrix.preRotate(rotation); matrix.mapPoints(keyPoints); float maxX, maxY; maxX = maxY = Float.MIN_VALUE; float minX, minY; minX = minY = Float.MAX_VALUE; for (int i = 0; i < keyPoints.length; i++) { if (i % 2 == 0) { if (maxX < keyPoints[i]) maxX = keyPoints[i]; if (minX > keyPoints[i]) minX = keyPoints[i]; } else { if (maxY < keyPoints[i]) maxY = keyPoints[i]; if (minY > keyPoints[i]) minY = keyPoints[i]; } } canvas.save(); needleBackgound.setBounds(0, 0, 15, 15); needleBackgound.draw(canvas); canvas.translate((maxX + minX) / -2f, (maxY + minY) / -2f); canvas.rotate(rotation, 8, 8); needle.setBounds(0, 0, 15, 15); needle.draw(canvas); canvas.restore(); } public void setBearing(float bearing) { this.bearing = bearing; } public void setOrientation(float orientation) { this.orientation = orientation; postInvalidate(); } }